perm filename SCNSER.MAC[IP,NET]1 blob sn#702358 filedate 1983-02-09 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00206 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00020 00002	TITLE SCNSER - TERMINAL SCANNER SERVICE  V575
C00021 00003	AFAL LOCAL EDIT HISTORY
C00030 00004	               TABLE OF CONTENTS FOR SCNSER
C00035 00005		SUBTTL	PARAMETER AND CONFIG DEFINITIONS
C00037 00006	IFNDEF STDALT,<STDALT==033>		VALUE OF STANDARD ALTMODE
C00038 00007		SUBTTL	DATA STRUCTURES -- LINTAB AND DSCTAB
C00041 00008		SUBTTL	DATA STRUCTURES -- LINE DATA BLOCK (LDB)
C00044 00009	MORE OF THE PROTOTYPE LINE DATA BLOCK
C00047 00010	RH OF LDBDCH - BITS 27-35 = LINE NUMBER, POINTER = LDPLNO
C00050 00011	MORE OF THE PROTOTYPE LINE DATA BLOCK
C00052 00012	ANOTHER BYTE WORD, FLAGS AT LEFT.
C00054 00013	IFN FTCIMP,<			(110)
C00056 00014	IFN FTLINK,<			(111)
C00058 00015	PAGE COUNTER WORD AND PAGE FLAGS
C00061 00016	FLAGS AND POINTER TO INTERUPT SERVICE ROUTINES
C00063 00017
C00065 00018	FIVE WORDS FOR REMOTE STATION TERMINAL STATUS
C00072 00019	IFN FTMIC,<		IF MIC INCLUDED
C00075 00020	DISPATCH TABLE FOR PTYS AND CTYS.
C00077 00021	DATA POINTERS INTO LDB
C00081 00022	LDPPSZ::POINT	6,LDBPAG(U),29		PAGE SIZE (# OF LINES)
C00085 00023		SUBTTL	DATA STRUCTURES -- TTY DEVICE DATA BLOCK (DDB)
C00088 00024		SUBTTL	TRANSMIT INTERRUPT ROUTINE
C00090 00025	XMTCHR -- ROUTINE TO RETURN THE NEXT CHARACTER TO SEND FROM
C00093 00026	COUNT UP THE CHARACTERS PHYSICALLY OUTPUT AND RETURN
C00096 00027	HERE WHEN A SPECIAL CONDITION BIT IS SET IN THE LDB.  THESE BITS
C00098 00028	FALL THROUGH TO HERE TO IDLE A LINE.
C00101 00029	PACKED IMAGE MODE (PIM) TRANSMIT INTERRUPT.
C00103 00030	HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBMIC IS NON-ZERO
C00106 00031	XMTOK:	MOVE	T2,LDBMIC(U)	GET MIC BITS
C00108 00032	HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBXNP IS NON-ZERO.
C00111 00033	XMTFI3:	MOVSI	T1,LPLSAP	WAITING TO DO A
C00114 00034	HERE WHEN BUFFERED AND FILLER OUTPUT DONE, AND LDBECT IS NON-ZERO
C00118 00035	CONTINUED FROM PREVIOUS PAGE
C00123 00036	ZAPECH:	SETZM	LDBECC(U)	FIX UP
C00125 00037	TOREQ::	MOVSI	T1,LDLIDL
C00127 00038	ROUTINE TO TAKE AN LDB OUT OF THE 'START OUTPUT' QUEUE
C00129 00039		SUBTTL	RECEIVE INTERRUPT ROUTINE
C00133 00040	CONTINUED FROM PREVIOUS PAGE
C00137 00041	HERE WITH T1=CHARACTER BITS (LH=0 IF NONE), T3=CHARACTER
C00141 00042	RECIN3:	LDB	T2,[POINT 7,T3,35]	GET SEVEN BITS OF CHARACTER
C00143 00043	IFN FTHDPX,<
C00147 00044	IFN FTCIMP,<			(110)
C00152 00045	(110) HERE WHEN PREVIOUS CHAR WAS NETWORK ESCAPE
C00156 00046	HERE ON RECEIVE INTERRUPT OF A CONTROL	-C CHARACTER
C00159 00047	HERE ON RECEIPT OF A ↑D CHARACTER
C00160 00048	HERE ON CONTROL H (BACKSPACE) TO DETERMINE HOW TO TREAT
C00161 00049	HERE ON RECEIPT OF A CARRIAGE RETURN (CONTROL M)
C00163 00050	HERE ON RECEIVE INTERRUPT OF A CONTROL Q (XON)
C00165 00051	IFN FTMIC,<			IF MIC
C00168 00052	HERE ON A CONTROL R
C00171 00053	HERE ON RECEIVE INTERRUPT OF CONTROL S (XOFF)
C00173 00054	IFN FTTVP,<
C00175 00055	PACKED IMAGE MODE (PIM) RECEIVE CHARACTER PROCESSING
C00178 00056	SNDXOF::MOVSI	T1,LPLXOF	GET THE "XOFF HAS BEEN SENT" BIT
C00179 00057	HERE ON A CONTROL U AT INTERRUPT LEVEL ONLY
C00183 00058	RIDLN:	PUSHJ	P,STOPCM	STOP COMCON
C00186 00059	RWARN:
C00189 00060	HERE ON A RUBOUT OR CONTROL W AT INTERRUPT LEVEL
C00192 00061	RIDEL5:	PUSHJ	P,TTVID
C00194 00062	HERE TO ECHO THE RUBOUT
C00197 00063	RIDEL8:	MOVNI	T2,-10(T2)	RELATIVE ADDRESS OF BYTE POINTER FOR ERASING
C00201 00064	RIDEL1:	SCNON
C00204 00065	IFN FTMODM,<			CODE INCLUDED ONLY IF MODEMS SUPPORTED
C00206 00066	DSROF1::MOVSI	T1,DSCHWC!DSCSWC!DSCIC2
C00208 00067	DSRON:
C00210 00068	CONTINUED FROM PREVIOUS PAGE
C00212 00069	TTFRC1:	AOS	(P)
C00215 00070	IFN FTDIAL,<
C00216 00071		SUBTTL	KI10 CONSOLE TERMINAL SERVICE
C00217 00072		SUBTTL	KS10 CTY AND KLINIK TERMINAL SERVICE
C00219 00073		SUBTTL	FILLERS AND SIMULATION ROUTINES
C00221 00074	CONTINUED FROM PREVIOUS PAGE
C00223 00075
C00227 00076	SETFI1:	TLNN	T1,CHFIL	THIS CHAR NEED FILLERS?
C00230 00077	CAN ONLY GET HERE FOR ↑U,↑Z OR ↑C. OTHERS NOT STORED IN INPUT BUFFER
C00232 00078	SETFLC -- ROUTINE TO SETUP THE FILLER CLASS FOR A LINE
C00234 00079	DISPATCH TO SET FILLERS FOR SOME CHARACTERS
C00236 00080	FILLKP:					POINTERS FOR BS AND VT
C00239 00081	VT06BP:	POINT	9,VT06TB
C00240 00082	VT06TB:	BYTE	(9)	377,377,377,210,240,377,377,377
C00242 00083	HERE TO GENERATE FILLERS OR SIMULATION FOR HORIZONTAL TAB
C00245 00084	FILLL:	TLNE	U,LDLFRM	THIS LINE HAVE FORM MOTION?
C00249 00085	DATA SENT OUT AS FILLERS
C00252 00086		SUBTTL	TIMING ROUTINE
C00254 00087		JRST	[PUSHJ P,TOREQ	REQUEUE SO OUTPUT STARTS
C00256 00088	IFN FTMODM,<
C00262 00089	DSCSC3:	MOVSI	T3,DSCBLI	SET FOR BLIND BIT
C00266 00090	DSTLBT:	POINT	6,DSCTAB##(T1),17	(1) TIME BYTE POINTER INDEXED BY T1
C00270 00091	SUBROUTINE TO TIME THE IMAGE MODE INPUT STATE, SET END OF FILE IF
C00273 00092	OUTPUT SERVICE ROUTINE FOR CTY
C00275 00093	ROUTINE TO ADJUST HORIZONTAL POSITION COUNT FOR CHARACTER TO
C00277 00094	HPOS -- SUBROUTINE TO FETCH THE CURRENT HORIZONTAL POSITION ON A LINE
C00278 00095	ROUTINE TO SUPPRESS BLANK LINES
C00280 00096	SUBROUTINE TO WAKE UP JOB IF IT IS IN TERMINAL INPUT WAIT. CALL WITH
C00283 00097	WAKJB:	PUSH	P,T2		SAVE AC'S
C00285 00098	TABLE OF CONTROL CHARACTERS - LH=BITS, RH=DISP ADDR ON RCV INT
C00294 00099	TTPWID:	POINT	8,TCRTAB(T1),7	POINTER TO TERMINAL WIDTH
C00297 00100	ROUTINE TO CHECK FOR A SPECIAL CHARACTER AND SET T1 TO ITS DESCRIPTOR
C00299 00101		SUBTTL	CHUNK HANDLERS
C00302 00102	NEWCKS -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN TAKING CHARACTERS
C00304 00103		SUBTTL	CHUNK HANDLERS -- ALLOCATION AND DEALLOCATION
C00306 00104		SUBTTL	CHUNK HANDLERS -- CLEAR BUFFERS
C00309 00105		SUBTTL	UUO LEVEL ROUTINES FOR BUFFERED I/O
C00310 00106	INPUT UUO PROCESSOR - CALLED FROM UUOCON ON INPUT UUO, DDB SET UP
C00313 00107	TTYIN1:	PUSHJ	P,TYICC		GET A CHARACTER
C00316 00108	OUTPUT UUO CALLS HERE
C00319 00109	CONTINUED FROM PREVIOUS PAGE
C00322 00110	TTMORE::PUSHJ	P,SAVE2##	SAVE P1-P2
C00325 00111	MORE50:	DPB	P1,BYTCNT	SAVE BYTE COUNT
C00327 00112		SUBTTL	DDT MODE CALLI'S
C00330 00113		SUBTTL	TTCALL AND TRMOP. -- TTCALL DISPATCH
C00332 00114	THE FOLLOWING TABLE IS USED TO PRE-CHECK AND DISPATCH THE TTCALL'S.
C00335 00115		SUBTTL	TTCALL AND TRMOP. -- OUTCHR AND IMAGE OUTCHR
C00337 00116		SUBTTL	TTCALL AND TRMOP. -- OUTSTR AND RESCAN
C00340 00117		SUBTTL	TTCALL AND TRMOP. -- SKPINL AND SKPINC
C00342 00118		SUBTTL	TTCALL AND TRMOP. -- GETLIN
C00345 00119		SUBTTL	TTCALL AND TRMOP. -- SETLIN, INCHSL, INCHWL, INCHRS & INCHRW
C00348 00120		SUBTTL	TTCALL AND TRMOP. -- TRMNO. UUO
C00350 00121		SUBTTL	TTCALL AND TRMOP. -- TRMOP. DISPATCH
C00353 00122	CONTINUED FROM PREVIOUS PAGE
C00355 00123	HERE IF REQUESTED FUNCTION NOT FROM 1 THRU TOPLN0-1
C00357 00124	TOPST4:	TLNN	T2,(TOP.IF)	THIS FUNCTION ILLEGAL FOR FRCLIN?
C00359 00125	TOPRED:	CAIL	T1,TOPLN1	LEGAL ITEM NUMBER?
C00361 00126	ROUTINE TO HANDLE FUNCTION 1041
C00363 00127	SUBROUTINE TO CHECK FOR READ PRIVS
C00366 00128	ERROR RETURNS
C00367 00129	TOPTB0 - TRMOP. ACTION FUNCTIONS LESS THAN 1000 
C00371 00130	TOPTB1 - TRMOP. READ/SET FUNCTIONS GREATER THAN 1000
C00377 00131	TOPSYR:	POINT	6,TOPTB1(P1),5	POINTER TO RANGE TABLE INDEX
C00378 00132		SUBTTL	TTCALL AND TRMOP. -- SKIPS AND CLEARS
C00380 00133		SUBTTL	TTCALL AND TRMOP. -- TRMOP. I/O
C00382 00134	INPUT A CHAR
C00383 00135		SUBTTL	TTCALL AND TRMOP. -- TRMOP. I/O SUBROUTINES
C00385 00136		SUBTTL	TTCALL AND TRMOP. -- TRMOP. DATASET FUNCTIONS
C00388 00137	IFE FTDIAL,<
C00389 00138	IFN FTDIAL,<
C00392 00139	IFN FTCAFE!FTKS10,<
C00393 00140		SUBTTL	TTCALL AND TRMOP. -- TYPE INTO TTY ON BEHALF OF A USER
C00396 00141		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  SET/CLEAR LDBMIC
C00398 00142		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  RETURN MIC STATUS
C00400 00143		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  READ ERROR RESPONSE TEXT
C00402 00144		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  LOG ALL TERMINAL OUTPUT
C00404 00145		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  MISCELLANEOUS MIC SUBROUTINES
C00406 00146	STILL FTMIC
C00408 00147	STILL FTMIC
C00410 00148	STILL FTMIC
C00412 00149		SUBTTL	SUBROUTINES FOR I/O
C00415 00150	CONTINUED FROM PREVIOUS PAGE
C00418 00151	SUBROUTINE TO DISCARD A COMMAND FROM INPUT BUFFER IF L2RECS STILL ON
C00420 00152	HERE ARE THE ROUTINES TO PERFROM VARIOUS "TTY INPUT" FUNCTIONS
C00422 00153	SUBROUTINE TO SEE IF A CONTROL C SHOULD BE ACTED ON OR STORED.
C00424 00154	ROUTINE TO PUT TERMINAL INTO MONITOR COMMAND MODE. DON'T CALL THIS
C00427 00155	ROUTINE TO MAKE THIS TERMINAL VISIBLE TO COMMAND DECODER, IF AT COM LEVEL
C00429 00156	TTFCOM::				FORCED COMMAND TABLE
C00431 00157		SUBTTL	COMMAND LEVEL ROUTINES
C00434 00158	DO FORCED COMMANDS OR CLEANUP 1ST, THEN FORCED KJOBS, THEN TYPED-IN COMMANDS
C00436 00159	TTKJOB::PUSHJ	P,CNCMOD	CONSOLE TO COMMAND LEVEL
C00438 00160	ROUTINES TO ATTACH TERMINAL TO A JOB
C00441 00161	TTYATI::
C00444 00162	CONTINUED FROM PREVIOUS PAGE
C00446 00163	SUBROUTINE TO LOOK FOR POSSIBLE LINE ALREADY ATTACHED TO TARGET JOB
C00449 00164	ROUTINE TO DETACH TERMINAL FROM A JOB.
C00452 00165	SUBROUTINE TO DISCONNECT A TERMINAL FROM A JOB WITHOUT SETTING TERMINAL TO MONITOR LEVEL
C00455 00166	ROUTINE TO RELEASE A TTY DDB. CALL WITH DDB SET UP.
C00457 00167	ROUTINE TO CLEAR A TTY DDB AND MAKE IT AVAILABLE TO THE POOL
C00460 00168	SUBROUTINE CALLED ON RESET FROM UUOCON
C00463 00169	SUBROUTINE TO RETURN ONE CHARACTER FROM THE INPUT BUFFER. CHARACTER
C00466 00170	ROUTINE TO SWITCH TERMINAL TO USER PROGRAM LEVEL AND START USER RUNNING
C00469 00171	HERE AT COMPLETION OF A COMMAND
C00472 00172		SUBTTL	SUBROUTINES FOR COMCON OR UUO LEVEL
C00476 00173	TYOVRG:	SCNOFF			NO INTERRUPTS
C00478 00174	SUBROUTINE TO SETUP A BYTE COUNT AND POINTER TO A USER'S BUFFER
C00480 00175	SUBROUTINE FOR COMMAND LEVEL OUTPUT
C00481 00176		$LOW			MUST BE IN THE LOW SEGMENT FOR ONCE-ONLY
C00483 00177	SUBROUTINE FOR ERROR MESSAGE TO CTY DURING PARITY ERROR STOP
C00485 00178		$HIGH			BACK TO THE HIGH SEGMENT
C00488 00179	ROUTINE TO FIND A FREE TTY DEVICE DATA BLOCK
C00491 00180	ROUTINE TO FIND A TTY DDB WHICH IS ATTACHED TO, I.E.
C00493 00181	ROUTINE CALLED WHEN DEVSRC CAN'T FIND DEVICE XXX (IN T1), AND
C00496 00182	SUBROUTINE TO PUT PHYSICAL NAME INTO T2 FOR U WHOSE LDB IS IN U
C00497 00183	SUBROUTINE TO FIND LDB FOR A PHYSICAL NAME, IF ITS A TTY
C00500 00184	SUBROUTINE TO FIND TTY FOR A JOB IN J (TTYFND) OR FOR
C00503 00185	SUBROUTINE TTYERP TO FIND TTY DDB FOR A MONITOR ERROR MESSAGE.
C00506 00186	CKATOU:	PUSHJ	P,CKATTO	FIRST MAKE SURE A LINE ATTACHED TO DDB
C00510 00187	HERE FROM UUOCON WHEN A TTY HAS BEEN INITED.
C00511 00188	TWAITI  --  WAIT FOR INPUT (CHARACTER OR LINE MODE)
C00514 00189	TTICHK  --  CHECK IF ANY INPUT IS AVAILABLE, LINE OR CHARACTER MODE
C00517 00190	SUBROUTINE TIWAIT TO WAIT FOR SOME INPUT, AND SEND XON IF NEEDED.
C00520 00191	ROUTINE TO CHECK IF AN XOFF HAS BEEN SENT OUT
C00522 00192	IFE FT2741,<
C00524 00193	IFN FTCIMP,<			(110)
C00527 00194	ROUTINE TO PUT SIXBIT NAME IN DEVNAM(DDB), AND TO SET PUNIT.
C00529 00195	IFN FTNET,<
C00531 00196		SUBTTL	ROUTINES FOR PTY
C00534 00197	CONTINUED FROM PREVIOUS PAGE
C00536 00198	MORE OF PTYPUT. SPECIAL CODE FOR CONTROL C
C00538 00199	SUBROUTINE TO SET DEFAULT TERMINAL CHARACTERSTICS
C00540 00200	IFN FTCIMP,<			(110)
C00543 00201	(110) SUBROUTINE TO SEND A CHARACTER TO A TELETYPE BUFFER.
C00545 00202	(271)(110) SUBROUTINE TO SEND CHARACTERS TO A JOB
C00548 00203	TWO SUBROUTINES TO INITIALIZE THE LDB. LDBCLR SETS UP THE BITS FROM
C00551 00204	CONTINUED FROM PREVIOUS PAGE
C00553 00205		SUBTTL	IMPURE DATA
C00555 00206		
C00556 ENDMK
C⊗;
TITLE SCNSER - TERMINAL SCANNER SERVICE  V575
SUBTTL R CLEMENTS/RCC/DAL/PMW/EJW/WRS	22 JUL 80
	SEARCH	F,S
IFN FTNET,<SEARCH NETPRM>
	$RELOC
	$HIGH

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
XP VSCNSR,575
ENTRY SCNSER
SCNSER::


;AFAL LOCAL EDIT HISTORY

;(1)	05-FEB-74, DALE STIMSON
;	MODULES AFFECTED: SCNSER
;	EDIT TYPE: CHANGE
;	ADD ROUTINES FROM WMU TO HANG UP A DATASET,
;	CHECK IF A LINE IS ATTACHED TO A REAL DATA SET,
;	AND DETACH AND ↑C A JOB WHEN ITS LINE HANGS UP.

;(107)	13-MAR-77, BOB BAKER
;	MODULES AFFECTED: S,SCNSER
;	EDIT TYPE: CHANGE
;	IMPLEMENT AUTO DETACHING OF INACTIVE DIAL-UP LINES.
;	THIS IS UNDER THE FT.DTF CONDITIONAL AND IS A REWORK
;	OF AN OLD WMU PATCH.  A CHECK OF DIAL-UP LINES IS MADE
;	EVERY <FT.DTF> SECONDS.  IF NO TTY ACTIVITY FOR EIGHT
;	CONSECUTVE CHECKS, JOB IS DETACHED AND HUNG UP.  FT.DTF
;	IS DEFINED IN S.

;(110)	08-APR-77, JIM MCCOOL
;	MODULES AFFECTED: CLOCK1,COMCON,COMDEV,COMMON,CORE1,
;			  F,S,SCHED1,SCNSER,SYSINI,UUOCON
;	EDIT TYPE: ENHANCEMENT
;	ADD CODE TO EXISTING MODULES TO SUPPORT RUTGERS ARPANET
;	INTERFACE.  LOCAL MODULES IMPINT, IMPSER, AND NETCON
;	ARE ADDED TO THE MONITOR WITH THIS EDIT.  MONGEN.MAC
;	AND FGEN.HLP HAVE BEEN MODIFIED TO DEFINE ADDITIONAL
;	HDWCNF PARAMETERS AND FEATURE TEST SWITCHES.

;(111)	08-APR-77, JIM MCCOOL
;	MODULES AFFECTED: CLOCK1,COMCON,F,S,SCNSER
;	EDIT TYPE: ENHANCEMENT
;	ADD RUTGERS TTY LINKING CODE TO THE MONITOR.  LOCAL
;	MODULE LNKSER IS ADDED TO THE MONITOR WITH THIS EDIT.
;	FGEN.HLP HAS BEEN MODIFIED TO DEFINE FEATURE TEST
;	SWITCH FTLINK.

;(146)	16-APR-78, BOB BAKER
;	EDIT TYPE: BUG FIX (IN IMP CODE)
;	MODULES AFFECTED: SCNSER
;	SYMPTOM: CHARACTERS FROM CROSSPATCHED TTY TO IMP SOMETIMES
;	NOT SENT OUT RIGHT AWAY.
;	DIAGNOSIS: WHEN IMPTTI IN IMPSER IS CALLED AT CLOCK LEVEL TO
;	TRANSFER CHARACTERS FROM CROSSPATCHED TTY TO IMP, IMPTTI CALLS
;	TYI IN SCNSER TO GET THE CHARS FROM TTY BUFFER.  TYI RETURNS
;	IMMEDIATELY IF IODERR IS TURNED ON IN S, BUT IMPTTI NEVER
;	SETS S UP AND IT CONTAINS SOME GARBAGE (USUALLY ZERO) PUT
;	THERE BY CLOCK1.
;	CURE: CLEAR S BEFORE CALLING TYI.

;(161)	15-JUN-78, JIM MCCOOL
;	MODULES AFFECTED: SCNSER
;	EDIT TYPE: BUG FIX (IN THE IMP CODE)
;	SYMPTOM: NETWORK ABORT OUTPUT (NETWORK ESCAPE, ↑O) IS BROKEN.
;	DIAGNOSIS: NETQUO IN SCNSER CALLS TSETBO IF THE TELNET FUNCTION
;	REQUESTED IS ABORT OUTPUT.  NETQUO STORES THE TELNET COMMAND
;	CHARACTER IT WANTS TO SEND IN T3 BUT TSETBO DESTROYS T3
;	CAUSING SOME UNDEFINED CHARACTER TO BE SENT AS A TELNET COMMAND
;	CURE: PRESERVE T3 AROUND THE CALL TO TSETBO

;(163)	21-JUL-78, JIM MCCOOL
;	MODULES AFFECTED: IMPSER, SCNSER
;	EDIT TYPE: ENHANCEMENT
;	SYMPTOM: MIC THINKS THAT LINES CROSSPATCHED TO THE NETWORK
;	CAN'T TAKE MORE INPUT WHEN IN FACT THEY ALMOST ALWAYS CAN.
;	DIAGNOSIS: MIC FUNCTIONS IN SCNSER KNOW NOTHING ABOUT THE ARPA
;	NET, SPECIFICALLY, THE MIC STATUS FUNCTION ONLY INDICATES THAT
;	THAT A JOB CAN TAKE MORE INPUT IF IT IS IN A TI WAIT STATE.
;	CURE: IN THE MIC GET STATUS ROUTINE, TOPMGT, IN SCNSER
;	ADD A CHECK TO SEE IF THE TTY LINE IS CROSSPATCHED TO THE
;	ARPANET AND IF SO, CALL A NEW ROUTINE, MICIMP, IN IMPSER
;	TO SEE IF THE CONNECTION CAN TAKE MORE INPUT
;
;	NOTE:  LOGICALLY, THIS MODIFICATION SHOULD BE PLACED IN
;	THE ROUTINE UJBSTX IN PTYSER SINCE THIS IS THE ROUTINE THAT
;	STANDARD DEC SCNSER CALLS TO DETERMINE IF A LINE CAN TAKE
;	MORE INPUT.  IT WAS DECIDED THAT THE MODIFICATION SHOULD
;	GO INTO SCNSER ITSELF SINCE PTYSER IS AS YET UNMODIFIED.

;(241)	24-mar-81, provan
;	Edit type: enhancement
;	modules affected: comcon, scnser, netcon
;	description:  add finger command to run SYS:FINGER
;		add finger server socket for arpanet to run SYS:FINGER.

;(251)	6-jan-81, provan
;	module affected: ScnSer
;	symptom: output to PTYs gets converted to upper case.
;		this is undesirable, since FTPSRV sends mail
;		through a PTY.
;	diagnosis: DEC always wanted this, but a bug in PTYSER
;		has foiled the attempt for several years.  in
;		7.01, the bug has been fixed, so upper case comes.
;	cure: clear LDLLCT for PTYs at LDBINI.  user may turn it
;		on if she wishes.

;(253)	11-jan-81, provan
;	module affected: ScnSer
;	symptom: too many <CRLF>s on output on NCR terminals.
;	diagnosis: using <CR> for a filler.  NCRs respond to
;		<CR> with <CRLF>.
;	cure: change filler for <CR> to <DEL> (377).

;(254)	14-jan-81, provan
;	module affected: ScnSer
;	symptom: no attach PSI interrupts
;	diagnosis: jump to wrong label
;	cure: make jump to TTYAT5 to TTYAT4.
;
;
;MCO-9878    25-FEB-82   OJ
;	MODULES AFFECTED:SCNSER
;	EDIT TYPE: SPR #31201
;	allow  output fill in image mode
;
;

;(265)	4-april-82, provan
;	module affected: ScnSer
;	complete work of edit (251) by setting TABS, FORM, and
;	No CRLF.  Output from PTYs is ALWAYS processed by
;	SOMETHING before it is ever output: don't limit that
;	something's options by replacing tabs and FF, etc.

;(270)	12-july-82, provan
;	modules affected: ImpInt, ImpSer, Common, ScnSer
;	description: insert some bug fixes discovered at
;	lll-mfe in the arpanet code.

;(271)	6-august-82, provan
;	modules affected: ScnSer, ImpSer
;	symptom:
;		monitor hangs in a tight loop around TopMt3.
;	diagnosis:
;		terminal is not unlocked at RECINT + N because
;		RECUNI takes an illegal skip return.
;	cure:
;		remove all skip returns from RECINU.
;		instead, allow LDBISR shut down data from
;		the IMP just like with any other terminal.

;(*)	END OF LOCAL EDIT HISTORY
;               TABLE OF CONTENTS FOR SCNSER
;
;
;                        SECTION                                   PAGE
;    1. PARAMETER AND CONFIG DEFINITIONS..........................   2
;    2. DATA STRUCTURES
;         2.1   LINTAB AND DSCTAB.................................   4
;         2.2   LINE DATA BLOCK (LDB).............................   5
;    3. MACROS TO MANIPULATE TERMINAL BUFFER STREAMS..............  13
;         3.3   TTY DEVICE DATA BLOCK (DDB).......................  16
;    4. TRANSMIT INTERRUPT ROUTINE................................  17
;    5. RECEIVE INTERRUPT ROUTINE.................................  30
;    6. KI10 CONSOLE TERMINAL SERVICE.............................  55
;    7. FILLERS AND SIMULATION ROUTINES...........................  56
;    8. TIMING ROUTINE............................................  68
;    9. CHUNK HANDLERS............................................  84
;   10. CHUNK HANDLERS
;        10.1   ALLOCATION AND DEALLOCATION.......................  85
;        10.2   CLEAR BUFFERS.....................................  86
;   11. UUO LEVEL ROUTINES FOR BUFFERED I/O.......................  87
;   12. DDT MODE CALLI'S..........................................  94
;   13. TTCALL AND TRMOP.
;        13.1   TTCALL DISPATCH...................................  95
;        13.2   OUTCHR AND IMAGE OUTCHR...........................  97
;        13.3   OUTSTR AND RESCAN.................................  98
;        13.4   SKPINL AND SKPINC.................................  99
;        13.5   GETLIN............................................ 100
;        13.6   SETLIN, INCHSL, INCHWL, INCHRS & INCHRW........... 101
;        13.7   TRMNO. UUO........................................ 102
;        13.8   TRMOP. DISPATCH................................... 103
;        13.9   SKIPS AND CLEARS.................................. 111
;        13.10  TRMOP. I/O........................................ 112
;        13.11  TRMOP. I/O SUBROUTINES............................ 113
;        13.12  TRMOP. DATASET FUNCTIONS.......................... 114
;   14. BYTE POINTERS INTO THE USER'S LDBMIC WORD................. 118
;   15. TYPE
;        15.1   - TYPE A STRING ON BEHALF OF A USER............... 119
;   16. CLEAR/SET
;        16.1   - CLEAR DOWN LDBMIC/SET UP LDBMIC................. 120
;   17. GET
;        17.1   GET THE STATUS FROM THE USERS LDBMIC WORD......... 121
;   18. RESPONSE
;        18.1   - RECORD AN ERROR MESSAGE......................... 122
;   19. LOG
;        19.1   - RECORD ALL UUO LEVEL OUTPUT..................... 123
;   20. SUBROUTINES CALLED FROM SCNSER AND OTHER PLACES........... 124
;   21. SUBROUTINES FOR I/O....................................... 128
;   22. COMMAND LEVEL ROUTINES.................................... 136
;   23. SUBROUTINES FOR COMCON OR UUO LEVEL....................... 149
;   24. ROUTINES FOR PTY.......................................... 169
;   25. IMPURE DATA............................................... 173
	SUBTTL	PARAMETER AND CONFIG DEFINITIONS

XP STTYBF,20

;DATASET TRANSACTION CODES FROM SCNSER TO/FROM XXXINT'S

XP DSTOFF,1		;DSCREC OR DSCTYP
XP DSTON,2		;DSCREC OR DSCTYP
XP DSTRNG,3		;DSCREC
XP DSTREQ,3		;DSCTYP
XP DSTINI,4		;TO AND FROM. SENDING COMPUTER WAS RESTARTED.
XP DSTSTS,5		;REQUEST DATA SET STATUS
XP DSTCRQ,10		;CALL REQUEST TO MODEM. WANT TO DIAL OUT.
XP DSTPND,20		;PRESENT NEXT DIGIT, TO AND FROM.
; NOTE - TO MODEM, 20-37 MEAN SEND DIGIT N-20
; WHERE DIGIT 17 MEANS END OF NUMBER (TO BOTH HARDWARE AND SOFTWARE)
; AND DIGIT 16 MEANS 5-SECOND DELAY TO SOFTWARE, FOR SECOND DIAL TONE.
XP DSTNAC,40		;NO ACTION -SYSINI (ONLY USER OF DSTREQ) SHOULD
			; NOT MODIFY LINE STATUS CODES (CARRIER ON/OFF)

;LINE CONTROL TRANSACTION CODES

XP LNTEHC,1	;ENABLE HUNG CHECK
XP LNTDHC,2	;DISABLE HUNG CHECK
IFNDEF STDALT,<STDALT==033>		;VALUE OF STANDARD ALTMODE
IFNDEF VTAB,<VTAB==10>			;VERTICAL TAB SPACING (MUST BE POWER OF 2)
IFNDEF FTMLOG,<XP FTMLOG,-1>		;NON-ZERO TO INCLUDE MIC LOG CODE

;SIZE OF CHUNKS

XP IMGTIM,↑D10		;MUST FIT IN LDPTIM FIELD. HUNG TIME FOR IMI


;HARDWARE PARAMETERS OTHER THAN THOSE IN THE XXXINT ROUTINES

CTY=120		;HARDWARE DEVICE NUMBER OF THE KA10 CONSOLE TERMINAL
	SUBTTL	DATA STRUCTURES -- LINTAB AND DSCTAB


;DATA STRUCTURES IN COMMON

;LINTAB:	BLOCK # OF LINES INCLUDING SCANNER,CTY AND PTY'S
;EACH WORD=	RH= LDB ADR
;		LH13-17=0 (FOR @ LINTAB)
;		LH 0-12 ARE COPIED INTO LDBDCH PERMANENT BITS BY LDBCLR
;		POINTER = LNPVRG

;DSCTAB:	BLOCK # OF DATASETS NEEDING TIMING
;		RH= LINKED TERMINAL LINE NUMBER FOR DATA
;		LH= TIME IN 14-17, ALSO DSCHWC,DSCSWC,DSCFAI

IFN FTMODM,<
XP DSCHWC,400000	;WHEN LAST HEARD FROM, THE HARDWARE CARRIER WAS ON
XP DSCSWC,200000	;THE SOFTWARE CONSIDERS THE CARRIER TO BE ON OR
			; TO BE COMING ON IMMINENTLY
XP DSCFAI,100000	;CARRIER WENT OFF, BUT MAY BE BRIEF FAILURE
			; EXCEPT FOR GPO 2B MODEM, MUST QUIT IMMEDIATELY
XP DSCNCR,040000	;NEW CARRIER FLAG, ON FOR FRACTION OF SECOND FOR CLOCK SYNC
XP DSCBLI,020000	;BLIND FLAG - IGNORE EVERYTHING FOR 1 SEC AFTER CARRIER ON
XP DSCDLW,010000	;DIALLER WAIT. WAITING FOR RESULTS FROM DIALLER
XP DSCDLF,004000	;DIALLER FAIL. UNSUCCESSFUL DIALLER ATTEMPT
XP DSCDLC,002000	;DIALLER COMPLETE. SUCCESSFUL DIALLER ACTION.
XP DSCEON,001000	;END OF NUMBER. SENT ALL DIGITS TO DIALLER.

IFN FT.DTF,<
XP DSCATM,700		;(107) MASK FOR TIMEOUT FIELD IN DSCTAB
>

IFE FT.DTF,<		;(107) IF NO DIAL-UP INACTIVITY TIMEOUT, DEFINE
XP DSCATM,0		;(107) DSCATM ANYWAY TO KEEP OTHER DEFINITIONS HAPPY
>

XP DSCTMM,77		;TIME MASK. MUST AGREE WITH DSTIMP POINTER.

;DEFINITIONS FOR INITIALIZATION ROUTINE IN SYSINI

XP DSCICL,DSCHWC!DSCSWC!DSCFAI!DSCDLW!DSCDLF!DSCDLC!DSCEON!DSCTMM!DSCATM	;(107)
XP DSCIC1,DSCHWC!DSCSWC
XP DSCIC2,DSCTMM!DSCFAI!DSCDLW!DSCDLF!DSCDLC!DSCEON!DSCATM	;(107)

> ;END OF FTMODM CONDITIONAL
	SUBTTL	DATA STRUCTURES -- LINE DATA BLOCK (LDB)

;PROTOTYPE LINE DATA BLOCK FOR A TTY (OR PTY) LINE

SCNLDB::
PHASE 0

LDBDDB::!XWD	ZERO5,0	;ADDRESS OF LINE'S ATTACHED DDB, IF ANY
XP LDBCMR,400000	;SIGN BIT OF LDBDDB IS COMMAND REQUEST BIT
			; MUST BE IN WORD ZERO, FOR @U, 13-17 MUST BE ZERO
XP LDBCMF,200000	;COMMAND FORCED. MEANS TYI ATE A CONTROL C
			; WHICH WAS DESTINED FOR COMCON, OR SOME OTHER COMMAND
			; IS TO BE FORCED, VIA LDPCMX. MUST BE IN SAME
			; WORD AS LDBCMR
XP LDBCMK,100000	;FORCING KJOB COMMAND
XP LDBDET,40000		;JOB DETACHED FROM THIS LINE DURING COMMAND
			;PROCESSING.  FORCE CLEANUP OF JOB/COMMAND
			;AT NEXT TICK.
			;BITS 9-12 ARE INDEX FOR FORCED COMMAND, 
			; POINTER = LDPCMX

LDICLR::!		;ON RESTART, START CLEARING HERE
LDBBKU:!0		;COPY OF LDBTIP AT LAST BREAK RECINT
LDBTIP::!0		;T2 TO PUT CHARACTERS IN INPUT BUFFER
LDBTIT::!0		;T2 TO TAKE CHARACTERS FROM INPUT BUFFER
LDBTIC::!0		;COUNT OF ECHOED CHARACTERS IN INPUT BUFFER
LDBBKC::!0		;COUNT OF BREAK CHARACTERS IN INPUT BUFFER
LDBTOP::!0		;T3 TO PUT CHARACTERS IN OUTPUT BUFFER
LDBTOT::!0		;T2 TO TAKE CHARACTERS FROM OUTPUT BUFFER
LDBTOC::!0		;COUNT OF CHARACTERS IN OUTPUT BUFFER
LDBECT::!0		;T2 TO TAKE CHARACTERS FROM INPUT FOR ECHOING
LDBECC::!0		;COUNT OF CHARACTERS TO ECHO
LDBCLP::!0		;COMMAND LINE POINTER (FOR COMCON)
LDBXNP::!0		;XON CLASS CHARACTER POINTER FOR OUTPUT
LDBFLP::!0		;FILLER CHARACTER POINTER FOR OUTPUT
LDBPBK::!0		;WORD OF UP TO 4 BREAK CHARACTERS (8 BIT)
			;FOR PACKED IMAGE MODE (PIM); SET WITH TRMOP 2037
LDBHPS::!0		;HORIZONTAL POSITION COUNTER.  COUNTS UP FROM
			;MINUS CARRIAGE WIDTH TO ZERO.
IFN FTRSP!FTACCT,<
LDBBCT::!0		;TOTAL COMMAND,,BREAK CHARACTER COUNT
LDBICT:!0		;TOTAL INPUT CHARACTER COUNT
LDBOCT:!0		;TOTAL OUTPUT CHARACTER COUNT
> ;END IFN FTRSP!FTACCT

LDICLE==:.-1		;ON RESTART, CLEAR THRU HERE
;MORE OF THE PROTOTYPE LINE DATA BLOCK
LDBDCH::!0		;DEVICE CHARACTERISTICS BITS

;BITS IN LH OF LDBDCH (CARRIED IN LH OF U DURING INTERRUPT ROUTINE)
;ORDER OF FIRST SEVERAL BITS IS IMPORTANT  --  SEE XMTSPC!

LDLIDL==:400000		;LINE IS IDLE.  IF CLEAR, WE ARE EXPECTING
			;A TRANSMIT INTERRUPT
			; MUST BE SIGN BIT.
LDLSTP==:200000		;OUTPUT WAS STOPPED BY CTRL/S
LDLSSO==:100000		;SCNSER STOPED OUTPUT. (HIT A TTY PAGE N BREAK)
LDLFCP==:040000		;A FORCE CHARACTER OR FILLERS ARE PENDING
			;NOTE! THIS BIT CAN BE SET WITH OUT FEAR IF ONE
			; WISHES TO HAVE XMTRDY SKIP RETURN, BUT IS NOT SURE
			; THAT A CHAR IS AVAILABLE. (SEE TTYDRQ)
LDLPIM==:020000		;TERMINAL WAS OPENED IN PIM MODE
LDLMIC==010000		;LDBMIC IS NON-ZERO
LDLDLR==004000		;SUPPRESS DOLLAR SIGN ON ALTMODES.
LDLNEC==:002000		;NO ECHO, DUE TO PROGRAM
LDLFCS==:001000		;LINE INITED IN FULL CHAR SET MODE
LDLIMI==:000400		;IMAGE INPUT (KEEP NULLS)
XP LDLCOM,000200	;LINE IS AT COMMAND LEVEL
LDLBKA==:000100		;BREAK ON ALL CHARACTERS (DDTIN, TTCALL)

;*** BEGINNING OF GROUP OF BITS POINTED TO BY LDPVR1 ***
;*** BEGINNING OF 4 BITS POINTED TO BY GETLP1 FOR GETLIN ****
XP LDLSLV,000040	;SLAVE. THIS TERMINAL MAY BE ASSIGNED.
XP LDLLCT,000020	;LOWER CASE TRANSLATE TO UPPER
XP LDLTAB,000010	;LINE ACCEPTS TABS, NOT SPACES.
XP LDLLCP,000004	;LOCAL COPY (NO ECHO)
;*** END OF BITS POINTED TO BY GETLP1 ***
XP LDLFRM,000002	;LINE ACCEPTS FF AND VT (ELSE USE LF'S)
XP LDLNFC,000001	;NO FREE CARRIAGE RETURN AT 72 COLUMNS
;*** END OF GROUP FOR LDPVR1 ***
XP LDLECH,LDLNEC!LDLBKA!LDLLCP

;BITS TO BE CLEARED ON A 140 RESTART
ZZL==LDLIDL+LDLIMI+LDLSTP+LDLSSO+LDLNEC+LDLFCP+LDLDLR+LDLBKA+LDLPIM+LDLMIC+LDLFCS
XP LDLIIF,LDLIMI+LDLFCS		;IMAGE INPUT OR FULL CHAR SET MODE
;RH OF LDBDCH - BITS 27-35 = LINE NUMBER, POINTER = LDPLNO

LDRPTY==:400000		;PSEUDO-TERMINAL
LDRCTY==:200000		;CONSOLE TERMINAL
;*** START OF GROUP OF BITS POINTED TO BY LDPVR2 ***
LDROSU==:100000		;OUTPUT SUPPRESS (↑O)
LDRDSD==:040000		;DATASET DATA LINE
LDR274==:020000		;LINE IS A 2741
LDRHLF==010000		;HALF DUPLEX LINE (TWX OR DC10C)
LDRRMT==:004000		;REMOTE NON-DATASET LINE
XP LDRDSR,LDRDSD+LDRRMT	;REMOTE OR DATA SET LINE (FOR PATCH)
			; SO CAN'T ATTACH TO PROJECT 1 #
;*** END OF GROUP FOR LDPVR2 ***
LDRREM==:002000		;TERMINAL AT REMOTE STATION
LDRSHC==:001000		;SUPPRESS HUNG CHECK -I.E. DON'T FORCE CHAR'S OUT
			;  WHEN NO XMIT FLAG.--SET BY 680 FOR SPECIAL
			;  DEVICES (E.G. 2741) & ITS OPR. TERMINAL

IFN FTCIMP,<		;(110)
 XP LDRIMP,000400	;(110) TTY IS AN ITY (IMP TTY)
			;(110) STOLEN BIT - DEC RESERVES 9 BITS FOR LINE NUMBER,
			;(110) BUT WE ONLY USE 8, AND THIS BIT MUST BE IN THE
			;(110) SAME HALF WORD AS LDRPTY.
LDRLIN==000377		;(110) MASK FOR LINE NUMBER
XP LDRPTI,LDRPTY!LDRIMP	;(110) LINE IS A  PTY OR IMP TTY
> ;END IFN FTCIMP	;(110)
IFE FTCIMP,<		;(110)
LDRLIN==000777		;(110) MASK FOR LINE NUMBER
>			;(110)

;BITS TO BE CLEARED ON A 400 RESTART
ZZR==LDRPTY+LDRCTY+LDRSHC+LDROSU

;DEFINITIONS OF BITS FOR GETLIN UUO, CLOSELY ASSOCIATED WITH ABOVE

GTLRDY==100		;BIT FOR GETLIN TO INDICATE WAITING BREAK CHAR
GTLT37==20		;MODEL 37 BIT (COPY OF LDLLCT)
GTLT35==10		;MODEL 35 BIT (COPY OF LDLTAB)
GTLLCP==4		;LOCAL COPY (OLD FULTWX) (COPY OF LDLLCP)
GTLXON==2		;XON IS TRUE (COPY OF L2RXON)
GTLMSK==LDR274!777	;BITS TO CLEAR ON GETLIN
LGLSET==GTLT37+GTLT35+GTLLCP+GTLXON	;MAY BE SET BY SETLIN


;BITS THAT ARE TESTED ON A CALL TO XMTCHR TO SEPARATE OUT
;THE NORMAL CASE FROM THE SPECIAL CASES.

DCHSPC==LDLIDL+LDLSTP+LDLSSO+LDLPIM+LDLFCP+LDLMIC,,LDRHLF

;MORE OF THE PROTOTYPE LINE DATA BLOCK

LDBOFL::!
LDBBYT::!0		;A WORD OF BYTES FOR THIS LINE

;BITS	POINTER	USE
;35-28	LDPECK	ECHO CHECK FOR HALF DUPLEX LINES
;27	L1RDEM	DEFERRED ECHO BIT.  SET BY SET TERMINAL DEFER
;26	L1RDEC	ECHO MAY ECHO 1 CHARACTER IF DEFERRED
;25	L1RDEL	ECHO MAY ECHO 1 LINE IF DEFERRED
;24-22	LDPCPU	CPU NUMBER--
;21	L1RCHP	CHANGE HARDWARE PARAMETERS FLAG (MEANINGUL EVEN FOR PTYS!)
;20	L1RMIF	MIC INTERLOCK FLAG
;19-15	LDPTIM	TIMEOUT ON IMAGE INPUT
;14-06	LDPSVC	SAVE CHARACTER DURING FREE CRLF, ↑X, ETC.
;05-03	POHPOS	OLD HORIZONTAL POSITION. NEEDED FOR TAB SIMULATION
;02-01	LDPFLC	COUNT OF NUMBER OF FILLERS BY CLASS
;0		1 IF FRONT END FOR THIS LINE IS DOWN.
;		 USE LDBOFL AS THE SYMBOL TO SKIPGE/SKIPL ON.
L1LOFL==:400000		;THE OFF-LINE BIT
L1RDEM==:1B27		;DEFERRED ECHO MODE
L1RDEC==:1B26		;MAY ECHO ONE CHARACTER (DEFERRED ECHO ONLY)
L1RDEL==:1B25		;MAY ECHO ONE LINE (DEFERRED ECHO ONLY)
L1RCHP==:1B21		;CHANGE HDW PARMS
L1RMIF==:1B20		;MIC INTERLOCK FLAG
LDIBCM==477777,,600000+L1RDEM+L1RDEC+L1RDEL+L1RCHP+L1RMIF+377 ;MASK TO CLEAR LDBBYT AT TTYINI. ALL ARE CLEARED
			; EXCEPT LDPFLC

;ANOTHER BYTE WORD, FLAGS AT LEFT.
LDBBY2::!0
;BITS	POINTER	USE
;35-28	LDPRCS	MOST RECENT RECEIVED CHARACTER
;20-27	LDPWID	WIDTH OF TERMINAL CARRIAGE
;18-19	BITS - SEE BELOW
;9-17	LDPDSC	DATASET CONTROL TABLE INDEX BACK POINTER
;0-8	BITS - SEE BELOW

L2LDEL==:400000		;LAST CHAR IN WAS A DELETE
L2LCCS==200000		;LAST CHAR IN WAS A ↑C
L2LHD1==100000		;XMT DONE FLAG SEEN THIS CHAR ON HDX LINE
L2LHD2==040000		;RCV DONE FLAG SEEN THIS CHAR ON HDX LINE
L2LHD3==020000		;IGNORING RCV INTS DUE TO ECHO CHECK ERR ON HDX LINE
L2LHD4==010000		;NEXT RCV INT WILL BE CUE AFTER ECHO CHK
L2LHD5==004000		;RECEIVE ECHO WAS IN FACT NOT SAME AS XMT CHAR
L2LSND==:002000		;SEND ALLOWED WHILE BUSY
L2LTAP==:001000		;↑Q FROM KEYBOARD TURNS ON L2RXON. SET BY .TERMINAL TAPE COMMAND

L2LHDM==L2LHD1!L2LHD2!L2LHD3!L2LHD4!L2LHD5

L2LCLR==L2LDEL!L2LCCS!L2LHDM!L2LSND!L2LTAP
			;CLEARED ON INITIALIZATION

L2RXON==:400000		;XON IS TRUE (PAPER TAPE INPUT)
L2RECS==200000		;EAT COMMAND SYNC, FOR TTCALL 10
IFN FTCIMP,<			;(110)

;(110) IMP DEVICE INFORMATION

LDBIMP::0		;(110) IF NON-ZERO, POINTER TO IMP DDB ADDR FOR CROSSPATCH

LDBQUO::0		;(110) QUOTE/ESCAPE CHARS AND DATA

;(110) BITS	POINTER	USE

;(110) 29-35	LDPQUO	QUOTE CHARACTER(INITIAL VALUE ↑N)
;(110) 22-28	LDPSFT	CASE SHIFT CHARACTER (NO INITIAL VALUE)
;(110) 15-21	LDPLCL	LOCAL TELNET ESCAPE (INITIAL VALUE ↑← OR ↑?)
;(110) 08-14	LDPNET	NETWORK ESCAPE CHARACTER (NO INITIAL VALUE)
;(110) 00-03		INDICATOR BITS:

LQLQUO==400000	;(110) PREVIOUS CHARACTER WAS QUOTE (SIGN BIT)
LQLSFT==200000	;(110) PREVIOUS CHARACTER WAS SHIFT		**KEEP IN
LQLDWN==:100000	;(110) SHIFT MODE (0=UP, 1=DOWN)		** ORDER
LQLNET==40000	;(110) NETWORK ESCAPE TYPED

> ;(110) END FTCIMP
IFN FTLINK,<			;(111)

;(111) TERMINAL LINK INFORMATION

;(111) BITS ARE DEFINED IN S.MAC FOR EASE OF USE BY BOTH SCNSER AND LNKSER

EXTERN	LNKSER		;(111) FORCE LINK LOADER TO INCLUDE LINK CODE

LDBLNK::0		;(111)

;(111) BITS	NAME	POINTER	USE

;(111) 0	LNKXMT		TTY IS ABOUT TO TRANSMIT BECAUSE OF LINK
;(111) 1	LNKACV		TTY HAS ACTIVE LINKS
;(111) 2	LNKREF		TTY IS REFUSING FURTHER LINKS
;(111) 3-11		LNKPTR	HEAD OF LINKED LIST OF LINKED TTY'S (LNKTBL IN COMMON)
;(111) 12	LNKECH		SENDING ECHO CHAR TO LINKED TTY
;(111) 13	LNKFLP		SEND INPUT FILLS TO LINKED TTY (LDBFLP)
;(111) 14	LNKOPD		ON CLOCK TICK, START OUTPUT TO THIS TTY IF NOT ACTIVE

LDBLKB::0	;(111) HEAD/TAIL OF LINKED LIST OF ECHO CHARACTERS IN
		;(111) INTERMEDIATE BUFFER. SEE LNKGET/LNKPUT IN LNKSER.

;(111) LOCATIONS EXTERNAL TO LNKSER:

INTERN	LDPSVC,FLLFLG,RCHLT1,LDBFLP
INTERN	LDBDCH,LDLIDL,LDBTOP,LDBTOT,TYOVRG
> ;(111) END FTLINK
;PAGE COUNTER WORD AND PAGE FLAGS
LDBPAG::!0
;BITS	POINTER USE
;30-35	LDPPCT	PAGE COUNTER
;24-29	LDPPSZ	PAGE SIZE
;18-23	LDPPFF	#LF'S REMAINING ON F.F. SIMULATION
;10-17	LDPACR	AUTO CRLF COUNTER
;8		WE ARE FORCING XMIT START VIA TOPOKE
;7	LDPDIS	TERMINAL IS A DISPLAY TERMINAL (HANDLES <DEL>'S)
;6		SEND ALL PENDING
;5		DON'T OUTPUT ANY MORE SINGLE L.F.'S
;4		SUPPRESS BLANK LINES (SET TERMINAL NO BLANK)
;3	LDPALT	ALTMODE CONVERSION (SET TERMINAL ALT)
;2		AN XOFF WAS SENT, XON NEEDED SOMETIME
;1		SET TERMINAL PAGE HAS BEEN DONE
;0		TERMINAL HAS NOT BEEN HEARD FROM IN THIS SECOND

LPLIRM==400000		;LOST TRANSMIT INTERRUPT BIT
LPLPAG==:200000		;SET TERMINAL PAGE COMMAND WAS EXECUTED
LPLXOF==100000		;SENT XOFF, ALWAYS SEND AN XON LATER
LPLALT==:40000		;ALTMODE CONV. (1:CONVERT 175,176 TO 033)
LPLBLK==:20000		;SUPPRESS BLANK LINES
LPLSLF==10000		;SUPPRESS LINE FEEDS
LPLSAP==:4000		;SEND ALL PENDING
LPLDIS==:2000		;SET IF THIS IS A DISPLAY TERMINAL
			; I.E., BACKSPACE MOVES CURSOR BACKWARDS
			; SPACE "ERASES" CHARACTER ON SCREEN
			; TERMINAL HAS ABILITY TO "HOME UP" CURSOR
LPLPOK==1000		;WE ARE FORCING XMIT START VIA TOPOKE (PREVENT RACE)
LPLACR==377		;AUTO CRLF COUNTER
LPLCLR==LPLIRM!LPLXOF!LPLBLK!LPLSLF!LPLSAP!LPLACR  ;CLEARED BY LDBINI
;FLAGS AND POINTER TO INTERUPT SERVICE ROUTINES
LDBISR::!BLOCK	1	
;BITS	POINTER	USE
;0	N/A	1 IF THE FRONT END IS CLEVER, 0 IF DUMB
;1-4	LDPTSP	TRANSMIT SPEED
;5-8	LDPRSP	RECEIVE SPEED
;9	LDPAPL	APL MODE
;10	LDPDBK	DEBREAK FEATURE EXISTS
;11	LDPRTC	CONTROL-R, CONTROL-T COMPATIBILITY
;12	LDPTDY	USER SAID "SET TERMINAL TIDY"
;13-17	CONTAIN T1 FOR @LDBISR(U)
;18-35	ADDRESS OF ISR DISPATCH TABLE

LILCFE==:(1B0)		;CLEVER FRONT END
LILRSP==:(17B4)		;RECEIVE SPEED
LILTSP==:(17B8)		;TRANSMIT SPEED
LILAPL==:(1B9)		;APL MODE
LILDBK==:(1B10)		;LINE HAS DEBREAK
LILRTC==:(1B11)		;CONTROL-R, CONTROL-T ARE PASSED TO PGM
LILTDY==:(1B12)		;DO NOT EXPAND OUTPUT

;FUNCTIONS ARE
ISRTYP==:0		;OUTPUT DATA IN T3 ON LINE POINTED TO BY U
ISRDSC==1		;DATA SET CONTROL
ISRCHK==:2		;TEST FOR LOST PIA
ISRINI==:3		;INIT ISR
ISRCHP==:4		;CHANGE HARDWARE PARAMETERS
ISRLPC==:5		;SEND LINE PARAMETER CONTROL MSG
ISRELE==:6		;SET ELEMENT #
ISRREM==:7		;DO REMOTE TERMINAL STUFF
ISROFL==:10		;SKIP IF FRONT END ON LINE

;LDBQUE -- QUEUED PROTOCOL WORD

LDBQUE::BLOCK	1

;BITS
;0-17		QUEUE HEADER
;18-36		NEXT LINE IN QUEUE

;TERMINAL TYPE WORD

LDBTTW::BLOCK	1
;0-7	LDPLCH	LAST CHAR READ BY COMCON.
;8		FREE
;9	LDLFSP	FULL SCNSER PTY
;10	LDLUAR	ON IF PROCESSING CONTROL R
;11	LDLUAW	ON IF PROCESSING CONTROL W
;12	LDLNAN	ON IF AN ALPHA-NUMERIC WAS SEEN WHILE PROCESSING CONTROL W
;		STOP ON SPACE OR TAB
;13-20	LDPFCT	FILLER REPEAT COUNTER
;21-28	PRPOS	POSITION OF PROMPT
;29-35	LDPTTT	TERMINAL TYPE AS SPECIFIED BY TTY TYPE COMMAND

LDLFSP==:400	;FULL SCNSER PTY
LDLUAR==200	;CONTROL R IN PROGRESS
LDLUAW==100	;CONTROL W IN PROGRESS
LDLNAN==40	;ON IF AN ALPHA-NUMERIC CHARACTER HAS BEEN SEEN


IFN FTD10H,<
;FLAGS FOR 2741 SUPPORT
LDBBCD::BLOCK	1
>
;FIVE WORDS FOR REMOTE STATION TERMINAL STATUS

IFN FTNET,<			;NETWORK RELATED LDB FIELDS

LDBREM::BLOCK	5		;WORDS REQUIRED FOR REMOTE TERMINALS

;			LAYOUT OF LDBREM FIELDS
;
; +0	BYTE (19)BITS-USED-BY-NETTTY, (1)0, (16)LAST-DAP-STATUS-MESSAGE-SENT
; +1	BYTE (36)LAST-CHARACTERISTICS-MESSAGE-SENT
; +2	BYTE (14)SLA, (14)DLA, (8)REMOTE-LINE-NUMBER
; +3	BYTE (4)2741-ELEMENT-NUMBER, (8)DRQ-COUNT, (8)EPM-SERIAL, (16)NODE-#
; +4MCR	BYTE (9)NEXT-CHAR-TO-OUTPUT, (9)DISCONNECT-TIMER, (9)JOB, (9)UNUSED
; +4VTM	BYTE (16)DELAYED-STATUS-MESSAGE, (2)0, (18)VTM-QUEUE-LINK


;DEFINE SYMBOLS FOR SOME LDBREM ENTRIES
LDBCCH==:LDBREM+1		;COMPRESSED CHARACTERISTICS WORD
LDBVTQ==:LDBREM+4		;NETVTM'S QUEUE LINK HALF-WORD

;			BITS USED IN LDBREM

;BITS USED BY BOTH NETVTM(LOCAL SET HOST) AND NETMCR(REMOTE TERMINALS)

LRLVTM==:(1B0)			;*** MUST BE SIGN BIT ***
				;  IF SET, THEN THIS IS A "LOCAL TERMINAL"
				;  THAT HAS "SET HOSTED" TO ANOTHER HOST.
LRLCON==:(1B1)			;IF SET, THEN TERMINAL IS "CONNECTED"
				;  (I.E. NCL CONNECT SEQUENCE IS COMPLETE)
LRLSTS==:(1B2)			;IF SET, THEN A "STATUS" MESSAGE IS REQUIRED
				;  SAME BIT, BUT DIFFERENT MSGS FOR VTM & MCR

;BITS USED ONLY BY NETVTM (LOCAL "SET HOST")

LRLSCH==:(1B3)			;IF SET, THEN A "CHARACTERISTICS" MESSAGE
				;  IS REQUIRED (WORKS LIKE "LRLSTS")
LRLDST==:(1B4)			;A "DELAYED" STATUS MESSAGE IS REQUIRED
				;  (USED TO OPTIMIZE MESSAGE TRAFFIC.
				;  THIS BIT HAS PRIORITY OVER LRLSTS)
LRLQED==:(1B5)			;IF SET, THEN VTM LINE HAS BEEN "QUEUED"
				;  BY "VTMENQ"
LRLDIP==:(1B6)			;IF SET, THEN WE HAVE/WANT-TO INITIATE A 
				; DISCONNECT ON THIS LINE
;BITS USED ONLY BY NETMCR ("NORMAL" REMOTE TERMINALS .. ALA DN87)

LRLTTO==:(1B3)			;LDPCHR HAS THE NEXT CHAR TO OUTPUT. THIS IS
				; NECESSARY SINCE THERE IS NO WAY TO TELL IF
				; XMTCHR WILL GIVE A CHAR WITH OUT GETTING IT.
LRLTTW==:(1B4)			;LINE IS WAITING FOR A DATA-REQUEST
LRLSCG==:(1B5)			;↑O ACTION REQUESTED (SEND CHAR GOBBLER)
LRLEPW==:(1B6)			;ECHO PIPELINE MARKER WAITING TO GO.
LRLIMO==:(1B7)			;INDICATES THAT REMOTE IS IN IMAGE MODE OUTPUT
LRLADR==:(1B8)			;USE OF THE AUTO-DIALER HAS BEEN REQUESTED
LRLXOF==:(1B9)			;AN XOFF (↑S) MESSAGE HAS BEEN REQUESTED
LRLCHR==:(1B10)			;THIS TERMINAL HAS RECEIVED AT LEAST 1
				; CHARACTERISTICS MSG.  (SEE NETTTY.MAC, ROUTINE
				; SCNMCR FOR DETAILS OF THE RACES INVOLVED...)
LRLDTR==:(1B11)			;RING/CARRIER BIT (SET/CLEARED BY STATUS MSGS
				; FROM THE -11)
LRLDSR==:(1B12)			;THE -10'S COPY OF WHAT IT THINKS LRLDTR
				; SHOULD BE.  (KEPT SO WE CAN TELL IF THE -11
				; CHANGED IT WHILE WE WEREN'T LOOKING)
LRLDSL==:(1B13)			;THIS LINE IS A DATA-SET LINE
LRLATO==:(1B14)			;INDICATES THAT THIS LINE POSSESSES THE AUTO-
				; BAUD CAPABILITY.  (SET/CLEARED BY THE ATTRIB
				; FIELD OF THE CONNECT MESSAGE)
LRLADL==:(1B15)			;INDICATES THAT THIS LINE POSSESES AN AUTO-
				; DIALER (ALSO SET BY CONNECT MESSAGE)
LRL741==:(1B16)			;INDICATES THAT THIS IS A 2741 LINE.
LRLTIW==:(1B17)			;SAYS THAT WE ARE IN TTY INPUT WAIT.  (I.E. WE
				; SHOULD UNLOCK THE 2741'S KEYBOARD)
LRRSHC==:1B18			;SAYS THAT THE LINE AT THE OTHER END HAS
				;  "SET HOST CAPABILITY".  (I.E. IT CAN
				;  RESPOND TO DISCONNECT MESSAGES).  NOT
				;  SET FOR DC72 LINES. SET FOR ALL OTHERS.

LRLCLR==:LRLDSR!LRLDTR!LRLTIW	;BITS THAT ARE OFF ON "VIRGIN" LINES
>;END OF IFN FTNET


;DEFINITIONS FOR SUPPORT OF RSX-20F TERMINALS

IFN FTKL10,<		;TTD'S ONLY ON A KL
LDBTTD::!0		;LINE INFO FOR -20F LINES
;	740000		;REMEMBERED TRANSMIT SPEED
;	036000		;REMEMBERED RECEIVE SPEED
LTLXOF==:1000		;SENT XOFF TO -20F
LTLRBS==:400		;REMOTE BIT SENT FOR -20F DATASETS
LTLCTO==:200		;NEED TO SEND FLUSH OUTPUT TO -20F
LTLAXF==:100		;AUTO-XOFF ENABLE SENT TO -20F
LTLACK==:40		;LINE WAITING FOR AN ACK
>;END FTKL10
IFN FTMIC,<		;IF MIC INCLUDED
;WORD FOR MIC TO USE
LDBMIC::0

;0	SET IF SOME BIT 1-14 IS SET
;1	SET IF A ↑C HAS BEEN TYPED
;2	SET IF OPERATOR CHAR SEEN IN COLUMN1
;3	SET IF ERROR CHAR SEEN IN COLUMN 1
;4	SET IF A ↑P HAS BEEN TYPED
;5	SET IF A ↑B HAS BEEN TYPED
;6	SILENCE THIS LINE
;7	LINE IN MONITOR MODE
;		NOT SET IN LDBMIC BUT IS SET ON A MICGET
;8	LINE IN USER MODE AND IN TI WAIT OR IN MONITOR MODE
;	AND CAN ACCEPT A COMMAND
;		NOT SET IN LDBMIC BUT IS SET ON A MICGET
;9	LINE IS IN COLUMN 1 ON OUTPUT
;	USED FOR ERROR AND OPERATOR CHECKING
;10	SET IF A ↑A HAS BEEN TYPED (ABORT)
;11	SET IF TERMINAL OUTPUT IS AVAILABLE
;15-21	ASCII CHAR TO BE TREATED AS OPERATOR CHAR
;		SET IN RESPONSE TO OPERATOR COMMAND
;		CLEARED IN RESPONSE TO NOOPERATOR COMMAND
;		OR ON LOGOUT
;22-28	ASCII CHAR TO BE TREATED AS ERROR CHAR
;		SET IN RESPONSE TO ERROR COMMAND
;		CLEARED IN RESPONSE TO NOERROR COMMAND
;		OR ON LOGOUT
;29-35	MIC MASTER JOB NUMBER - ENABLES MORE THAN ONE MIC TO RUN

LDLCHK==400000		;SOMETHING EXCITING HAPPENED
LDLMCC==200000		;↑C TYPED
LDLOPC==100000		;OPERATOR CHARACTER SEEN IN COLUMN 1
LDLERC==40000		;ERROR CHARACTER SEEN IN COLUMN 1
LDLMCP==20000		;↑P TYPED
LDLMCB==:10000		;↑B TYPED
LDLSIL==4000		;THIS LINE IS .SILENCE'D
LDLMMM==2000		;LINE IN MONITOR MODE (MICGET)
LDLMTI==1000		;LINE IN INPUT READY STATE
LDLCL1==400		;CARRIAGE IS IN COLUMN 1
LDLMCA==200		;↑A TYPED
LDLRSP==100		;ERROR RESPONSE
LDLRSY==:40		;RESPONSE CODE SYNC
IFN FTMLOG,<
LDLLOG==20		;MIC IS LOGGING

LDBLOT::0		;LOG TAKER,,COUNT OF CHARS TO LOG
LDBLOC::0		;COUNT OF CHARACTERS TO LOG
> ;END OF FTMLOG CONDITIONAL
> ;END OF MIC CONDITIONAL
DEPHASE

LDBLEN==:.-SCNLDB		;SIZE OF DATA BLOCK FOR A LINE
;DISPATCH TABLE FOR PTYS AND CTYS.

IFN FTKI10!FTKS10,<
CTYDSP::JRST	CTYTYO		;TYPEOUT
	POPJ	P,0		;MODEM CONTROL
	POPJ	P,0		;ONCE A SECOND
	POPJ	P,0		;INITIALIZATION
	POPJ	P,0		;CHANGE HARDWARE PARMS
	POPJ	P,		;LINE PARM CONTROL
	POPJ	P,		;SET ELEMENT
	POPJ	P,		;REMOTE STUFF
	JRST	CPOPJ1##	;IS LINE UP?
>

ERRDSP::POPJ	P,0		;TYPEOUT
	POPJ	P,0		;MODEM CONTROL
	POPJ	P,0		;ONCE A SECOND
	POPJ	P,0		;INITIALIZATION
	POPJ	P,0		;CHANGE HARDWARE PARMS
	POPJ	P,		;LINE PARM CONTROL
	POPJ	P,		;SET ELEMENT
	POPJ	P,		;REMOTE STUFF
	JRST	CPOPJ1##	;IS LINE UP?

;LINE SPEED MNEMONICS

LS0000==:0	;ZERO BAUD
LS0050==:1	;50 BAUD
LS0075==:2	;75 BAUD
LS0110==:3	;110 BAUD
LS0134==:4	;134.5 BAUD
LS0150==:5	;150 BAUD
LS0200==:6	;200 BAUD
LS0300==:7	;300 BAUD
LS0600==:10	;600 BAUD
LS1200==:11	;1200 BAUD
LS1800==:12	;1800 BAUD
LS2400==:13	;2400 BAUD
LS4800==:14	;4800 BAUD
LS9600==:15	;9600 BAUD

;DATA POINTERS INTO LDB

LDPLCH:	POINT	8,LDBTTW(U),7		;POINTER TO LAST CHAR COMCON READ
LDPFCT:	POINT	8,LDBTTW(U),20		;POINTER TO FILLER REPEAT COUNTER
LDPTTT::POINT	7,LDBTTW(U),35
LDPCPU::POINT	3,LDBBYT(U),24
LDPFLC::POINT	2,LDBBYT(U),2		;POINTER TO INDEX OF FILLER CLASSES
IFE FTCIMP,<				;(110)
LDPLNO::POINT	9,LDBDCH(U),35		;POINTER TO HARDWARE LINE NUMBER
>					;(110)
IFN FTCIMP,<				;(110)
LDPLNO::POINT	8,LDBDCH(U),35		;(110)POINTER TO HARDWARE LINE NUMBER
>					;(110) RESPECTS STOLEN BIT FOR LDRIMP
LDPSVC:	POINT	9,LDBBYT(U),14		;POINTER TO SAVED CHARACTER
					;TO BE USED AFTER FILLERS SENT
LDPTIM:	POINT	5,LDBBYT(U),19		;POINTER TO FIELD WHICH TIMES OUT
					; IMAGE MODE INPUT
IFN FTHDPX!FTTRACK,<
LDPECK::POINT	8,LDBBYT(U),35		;POINTER TO LAST CHARACTER SENT, FOR
					; ECHO CHECK ON HDX LINE
>
LDPDEM::POINT	1,LDBBYT(U),↑L<L1RDEM>	;POINTER TO L1RDEM BIT
LDPFRM:	POINT	1,LDBDCH(U),↑L<(LDLFRM)>;POINTER TO HARDWARE FORM FEED BIT
LDPTAB:	POINT	1,LDBDCH(U),↑L<(LDLTAB)>;POINTER TO HARDWARE TABS BIT
LDPLCT:	POINT	1,LDBDCH(U),↑L<(LDLLCT)>;POINTER TO LOWER CASE BIT
LDPIMI::POINT	1,LDBDCH(U),↑L<(LDLIMI)>;POINTER TO IMAGE MODE FLAG
LDPPIM::POINT	1,LDBDCH(U),↑L<(LDLPIM)>;POINTER TO PIM MODE FLAG
LDPFCS::POINT	1,LDBDCH(U),↑L<(LDLFCS)>;POINTER TO FULL CHAR SET FLAG
LDPBKA::POINT	1,LDBDCH(U),↑L<(LDLBKA)>;POINTER TO BREAK ON ALL CHARS FLAG
LDPALT:	POINT	1,LDBPAG(U),↑L<(LPLALT)>;POINTER TO ALTMODE CONVERSION BIT
LDPDIS:	POINT	1,LDBPAG(U),↑L<(LPLDIS)>;POINTER TO DISPLAY TERMINAL BIT
LDPOSU:	POINT	1,LDBDCH(U),↑L<LDROSU>	;POINTER TO OUTPUT SUPPRESSION (↑O) BIT
PRPOS:	POINT	8,LDBTTW(U),28		;POINTER TO HORIZONTAL POSITION AFTER PROMPT
POHPOS:	POINT	3,LDBBYT(U),5		;POINTER TO LOW 3 BITS OF HPOS
					; BEFORE A TAB (FOR TAB SIMULATION)
LNPVRG:	POINT	13,LINTAB##(T1),12	;POINTER TO LOW CORE COPY OF BITS FOR RESTART
LDPVR1:	POINT	6,LDBDCH(U),17		;POINTER TO STORE SOME OF ABOVE BITS
LDPVR2:	POINT	5,LDBDCH(U),24		;POINTER TO STORE SOME MORE OF ABOVE.
LDPCMX::POINT	4,LDBDDB(U),12		;POINTER TO INDEX OF FORCED COMMANDS
IFN FTTRACK,<
LDPRCS:	POINT	8,LDBBY2(U),35		;POINTER TO RECEIVED CHARACTER
					; SAVED FOR WATCHING IN LIGHTS.
>
LDPWID::POINT	8,LDBBY2(U),27		;POINTER TO WIDTH OF TERMINAL CARRIAGE
IFN FTMODM,<
LDPDSC::POINT	9,LDBBY2(U),17		;POINTER TO DATASET CONTROL TABLE INDEX
>
LDPPSZ::POINT	6,LDBPAG(U),29		;PAGE SIZE (# OF LINES)
LDPPCT:	POINT	6,LDBPAG(U),35		;PAGE COUNTER
LDPPFF:	POINT	6,LDBPAG(U),23		;L.F. COUNTER FOR SIMULATION OF V.T. & F.F.
LDPDEB::POINT	2,LDBBYT(U),26		;POINTER TO DEFERRED ECHO BITS
IFN <FTCAFE!FTKS10!FTNET>,<
LDPSPD::POINT	8,LDBISR(U),8		;BOTH SPEEDS
>
LDPRTC::POINT	1,LDBISR(U),11		;↑R, ↑T COMPATIBILITY
LDPRSP::POINT	4,LDBISR(U),8		;RECEIVE SPEED
LDPTSP::POINT	4,LDBISR(U),4		;TRANSMIT SPEED
LDPAPL::POINT	1,LDBISR(U),9		;APL MODE BIT
LDPDBK::POINT	1,LDBISR(U),10		;DEBREAK FEATURE EXISTS
LDP274::POINT	1,LDBDCH(U),22		;LINE IS A 2741
LDPTDY::POINT	1,LDBISR(U),12		;DO NOT EXPAND OUTPUT
LDPACR::POINT	8,LDBPAG(U),17		;AUTO CRLF POINT


IFN FTNET,<
;FIELDS IN THE LDBREM AREA.  (USED BY NETWORK LINES)

LDPSTS::POINT	16,LDBREM+0(U),35	;CONTAINS THE LAST DAP STATUS MESSAGE
LDPSLA::POINT	13,LDBREM+2(U),12	;CONTAINS OUR SOURCE LINK ADDRESS
LDPDLA::POINT	13,LDBREM+2(U),25	;CONTAINS OUR DESTINATION LINK ADDRESS
LDPRLN::POINT	10,LDBREM+2(U),35	;LINE NUMBER AT REMOTE STATION
LDPELE::POINT	4,LDBREM+3(U),3		;2741 ELEMENT NUMBER
LDPDRQ::POINT	8,LDBREM+3(U),11	;NUMBER OF DATA-REQUESTS FROM REMOTE
LDPEPM::POINT	8,LDBREM+3(U),19	;SERIAL NUMBER OF LAST EPM FROM REMOTE
LDPRNN::POINT	16,LDBREM+3(U),35	;NUMBER OF NODE OWNING THIS TTY
LDPRNF::POINT	16,LDBREM+3(F),35	; SAME AS ABOVE, EXCEPT INDEXED BY "F"

LDPCHR::POINT	9,LDBREM+4(U),8		;IF LRLTTO =1, THIS CONTAINS THE NEXT
					; OUTPUT CHARACTER
LDPADT::POINT	9,LDBREM+4(U),17	;AUTO-DISCONNECT TIMER.
LDPJOB::POINT	9,LDBREM+4(U),26	;POINTER TO JOB (ONLY FOR CONNECTS)
LDPDST::POINT	18,LDBVTQ(U),17		;"DELAYED" STATUS FOR VTM
>;END OF IFN FTNET
IFN FTMIC,<
LDP.OP:	POINT	7,LDBMIC(U),21		;OPERATOR CHARACTER
LDP.ER:	POINT	7,LDBMIC(U),28		;ERROR CHARACTER
LDPMJN:	POINT	7,LDBMIC(U),35		;MIC MASTER JOB NUMBER
> ;END IFN FTMIC

IFN FTCIMP,<			;(110)
LDPQTB::			;(110) TABLE OF POINTERS - INDEXED BY CODE
LDPQUO::POINT	7,LDBQUO(U),35	;(110) QUOTE CHAR	** DO NOT
LDPSFT::POINT	7,LDBQUO(U),28	;(110) SHIFT CHAR	** CHANGE
LDPLCL::POINT	7,LDBQUO(U),21	;(110) LOCAL ESC	**  THIS
LDPNET::POINT	7,LDBQUO(U),14	;(110) NETW ESC	        ** ORDER
NQUPTS==.-LDPQTB		;(110) NUMBER OF POINTERS
XP	MNQUPT,-NQUPTS		;;(110) NEGATIVE NUMBER OF POINTERS

LDPSMD:	POINT	2,LDBQUO(U),↑L<LQLDWN,,0>	;(110) POINTER TO SHIFT/MODE BITS

INDSTM==1B26	;(110) DISABLE IMAGE MODE TIMEOUT - SET BY SETSTS

> ;(110) END FTCIMP

;BITS TO BE CLEARED ON A 140 RESTART

LDIDCM:	XWD	ZZL,ZZR			;TO CLEAR BITS IN LDBDCH
	SUBTTL	DATA STRUCTURES -- TTY DEVICE DATA BLOCK (DDB)

;PROTOTYPE SCANNER DDB. REPLICATED BY ONCE. ONE FOR EACH JOB.

	$LOW
TTYLST::			;LABEL FOR FIRST TTY DDB IN CHAIN

SCNDDB::			;GLOBAL LABEL
PHASE 0

	SIXBIT	/TTY0/		;DEVNAM (PHYSICAL NAME)
	XWD	0,STTYBF+1	;DEVCHR. SIZE OF USER BUFFER
	0			;DEVIOS
	XWD	0,SCNDSP	;DEVSER
	XWD	DVTTY+DVIN+DVOUT,<<1←A>+<1←AL>+<1←PIMMOD>+<1←I>>	;DEVMOD
	0			;DEVLOG (LOGICAL NAME)
	0			;DEVBUF
	0			;DEVIAD
	0			;DEVOAD
	0			;DEVSTS
	XWD	.TYTTY,0	;DEVSTA
	0			;DEVXTR
	0			;DEVEVM
	0			;DEVPSI
	0			;DEVESE
	0			;DEVHCW
	707000,,0		;DEVCPU
	0			;DEVJOB
DDBLDB::!0			;LH=FREE
				;RH=DDBLDB LINKS TO THE LDB.
DEPHASE
XP SCNDDS,.-SCNDDB
	$HIGH
BYTCNT:	POINT	12,DEVOAD(F),12

;DATA WITHIN THE DDB

;USE OF DEVIOS

;LEFT HALF
XP TTYOUW,400000	;REMEMBERS THAT IF IN IOW, IT IS FOR OUTPUT, AS
			; OPPOSED TO INPUT. I.E., WHICH INT WAKES JOB
FRCEND==:200000		;IN IMAGE INPUT, FORCE END OF FILE DUE TO TIMING
IOLBKA==100000		;TEMP INTERNAL BIT TO PRESERVE BKA OVER ↑C/CONT

;RIGHT HALF
IFN FTCIMP,<		;(110)
CTLSUP==4000		;(110) SUPPRESS ECHO OF CTRL CHAR
>			;(110)
IOSBKA==1000		;BREAK ON ALL CHARACTERS
IOSTEC==400		;SUPPRESS ECHO OF DOLLAR SIGN ON ALTMOD
IOSNEC==:200		;USER (E.G. LOGIN) SUPPRESSING ECHO
IOSFCS==100		;USER WANTS ALL CHARACTERS.
	SUBTTL	TRANSMIT INTERRUPT ROUTINE

;ENTRY FROM DEVICE-DEPENDENT INTERRUPT SERVICE ROUTINE ON A
; TRANSMIT-DONE INTERRUPT. THE HARDWARE LINE NUMBER IS
; IN AC U.  ENTER AT XMTIN1 IF U IS SETUP TO THE LDB ADDRESS.


XMTINT::MOVE	U,LINTAB##(U)	;GET LINE DATA BLOCK ADDRESS
XMTIN1::MOVSI	T1,L1LOFL
	ANDCAM	T1,LDBOFL(U)
	SKIPGE	LDBDCH(U)	;ARE WE EXPECTING THIS?
	JRST	XMTDMC		;NO, GO UNLOCK KEYBOARD
	PUSHJ	P,XMTCHR	;GET A CHARACTER FROM THE CHUNKS
	  POPJ	P,		;END OF STRING
	MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	;CLEAR SINCE JUST SENT A CHARACTER
IFN FTHDPX,<
	MOVSI	T1,L2LHDM	;HALF DUPLEX BITS
	ANDCAM	T1,LDBBY2(U)	;CLEAR THEM IN THE LDB
>
	MOVEI	T1,ISRTYP	;FUNCTION DESIRED FROM DEVICE DRIVER
	PJRST	@LDBISR(U)	;GO DO IT

;XMTCHR -- ROUTINE TO RETURN THE NEXT CHARACTER TO SEND FROM
;	   A TERMINAL OUTPUT BUFFER
;
;CALL
;	MOVE	U,LDB ADDRESS
;	PUSHJ	P,XMTCHR
;	  <IDLE CONDITION>
;	<CHARACTER IN T3>

XMTHCH:	MOVE	T1,LDBDCH(U)	;GET SPECIAL BITS FROM LDB
	TRZ	T1,LDRHLF	;BUT CLEAR HALF DUPLEX BIT FOR NOW
	JRST	XMTCH1		;JOIN XMTCHR

XMTCHR::MOVE	T1,LDBDCH(U)	;GET SPECIAL BITS FROM LDB
XMTCH1:	TDNE	T1,[DCHSPC]	;ANY UNUSUAL STATES?
	JRST	XMTSPC		;YES, GO HANDLE SPECIAL CASES
XMTCH2:	SCNOFF			;NO INTERRUPTS WHILE TAKING CHARACTERS
	SOSGE	T4,LDBTOC(U)	;COUNT DOWN LENGTH OF OUTPUT STREAM
	JRST	ZAPBUF		;IF EMPTY STREAM.  GO RESET COUNT
	LDCHKR	T3,LDBTOT(U)	;TAKE NEXT CHARACTER FROM STREAM
XMTCH3:	SCNON			;HAVE CHARACTER, ALLOW OTHERS TO ACCESS
	CAIN	T4,↑D50		;HAVE WE REACHED THE WAKE THRESHOLD?
	PUSHJ	P,XMTWAK	;YES, GO WAKE JOB IF WAITING
IFN	FTMIC,<
	MOVE	T4,LDBMIC(U)	;GET MIC BITS
	TLNE	T4,LDLSIL	;LINE SILENCED
	JRST	XMTCHR		;YES, EAT THE CHARACTER
>
XMTCH4:	TRNE	T3,400		;IS THIS AN IMAGE MODE CHARACTER?
	JRST	XMTCN6		;YES, COUNT IT AND RETURN
	ANDI	T3,177		;CLEAR POSSIBLE PARITY BIT
	SKIPGE	T1,CHTABL(T3)	;GET SPECIAL BITS, TEST FOR UNUSUAL CHAR
	JRST	XMTSPO		;THIS MAY REQUIRE FILL OR BLANK SUPPRESS
	AOSG	LDBHPS(U)	;INCREMENT HORIZONTAL POSITION
	JRST	XMTCN5		;RETURN IF NOT END OF CARRIAGE
	PUSHJ	P,PTBTCH##	;CHECK FOR REGULAR PTY
	  JRST	XMTCN5		;NO FREE CRLF FOR LOG FILES
	MOVE	T2,LDBDCH(U)	;GET CHARACTERISTICS WORD
	TLNE	T2,LDLNFC	;USER WANT FREE <CR><LF>?
	JRST	XMTCN5		;NO, JUST SEND THE CHARACTER
	TLZ	T1,CHALT!CHUAE!CHCRE  ;OUTPUT CHARACTERS GO STRAIGHT
	PUSHJ	P,SETCRF	;YES, GO SETUP A CRLF FILLER
	  JRST	XMTFIL		; AND SEND THE FILLER INSTEAD
	JRST	XMTCN5		;GO SEND THE CHARACTER AFTER ALL!
;COUNT UP THE CHARACTERS PHYSICALLY OUTPUT AND RETURN

XMTCNT:
IFN FTTVP,<
	CAIN	T3,12		;LINEFEED?
	PUSHJ	P,INCPCT	;DUMP PAGE COUNTER
>
XMTCN4:
IFN FTCIMP,<			;(110)
	SKIPE	LDBIMP(U)	;(110) IF AN IMP, DON'T TRASH IMAGE BIT YET
	JRST	XMTCN6		;(110) JUST CHECK FOR TELNET CONTROL
>;(110)
;	ANDI	T3,177		;WE MAY HAVE TRASHED PARITY, SO  [9879]
;	MOVE	T1,CHTABL(T3)	;GET THE CHAR'S BITS   [9879]
	ANDI	T3,777		;GET RID OF ANY EXTRA BITS   [9879]
	LDB	T1,[POINT 7,T3,35] ;GET THE 7 LOW ORDER BITS [9879]
	MOVE	T1,CHTABL(T1)	;GET THE CHAR'S BITS
	TRNN	T3,400		;IMAGE MODE FILL?
	  JRST	XMTCN6		;YES, DON'T MESS WITH PARITY

XMTCN5:	TLNN	T1,CHEPAR	;IF THE CHAR REQUIRES PARITY
	TRO	T3,200		;THEN MAKE THE PARITY EVEN
XMTCN6:
IFN FTCIMP,<			;(110)
	TRNE	T3,400		;(110) IMAGE BIT SET?
	SKIPN	LDBIMP(U)	;(110) AND XPATCHED?
	JRST	XMTCNX		;(110) NO, LEAVE IMAGE ALONE
	ANDI	T3,377		;(110) GET 8 BITS OF CHAR
	TRNE	T3,200		;(110) TELNET CONTROL?
	JRST	XMTCHR		;(110) YES, NO ECHO
XMTCNX:	>			;(110)
IFN FTRSP!FTACCT,<		;IF COUNTING CHARACTERS, THEN
	AOS	LDBOCT(U)	;COUNT CHARACTERS OUTPUT THIS LINE
	AOS	%SCNXI		;AND TOTAL CHARACTERS OUTPUT BY SYSTEM
> ;END IFN FTRSP!FTACCT
	PJRST	CPOPJ1##	;RETURN THE CHARACTER



;HERE FOR UNUSUAL CHARACTER ON OUTPUT

XMTSPO:	HLL	U,LDBDCH(U)	;SETUP LEFT HALF OF U WITH BITS
	TLNN	T1,CHEPAR	;NEED A PARITY BIT?
	TRO	T3,200		;YES, ADD IT
IFN FTTBLK,<
	MOVSI	T2,LPLBLK
	TDNE	T2,LDBPAG(U)
	PUSHJ	P,BLSUPO	;CHECK FOR TERMINAL NO BLANKS
>
	PUSHJ	P,ADJHP
	PUSHJ	P,SETFLO	;SETUP FILLERS IF ANY NEEDED
	  JRST	XMTFIL		;FILLS NEEDED, GO SEND THEM FIRST
IFN FTTVP,<
	CAIN	T3,12		;IF LINE FEED
	PUSHJ	P,INCPCT	; INCREMENT PAGE COUNT
>
	JRST	XMTCN6		;NONE NEEDED, JUST RETURN IT
;HERE WHEN A SPECIAL CONDITION BIT IS SET IN THE LDB.  THESE BITS
;ARE PLACED IN LDBDCH IN SUCH A WAY THAT A JFFO INSTRUCTION CAN
;BE USED TO FIND THE CONDITION THAT NEEDS ATTENTION FIRST.

XMTSPC:	HLL	U,LDBDCH(U)	;CARRY LEFT HALF OF LDBDCH IN U 
	AND	T1,[LDLIDL!LDLSTP!LDLSSO!LDLFCP!LDLPIM!LDLMIC,,0]
	JFFO	T1,XMTSP1	;GET FIRST FLAG SET
	MOVE	T1,LDBDCH(U)	;REFRESH BITS
	JRST	XMTHDX

XMTSP1:	JRST	@[EXP XMTCIS,XMTSTP,XMTSSO,XMTFLC,XMTPIM,XMTMIC](T2)

XMTSTP:
XMTSSO:	SKIPN	LDBFLP(U)	;KROCK - ALLOW FILLER POINTER TO FINISH
	JRST	XMTIDL		;NO FILLER, NO OUTPUT
				;FALL INTO XMTFLC

XMTFLC:	SCNOFF			;NO INTERRUPTS WHILE TRY TO CLEAR FPC
	SKIPE	LDBXNP(U)	;XON CLASS POINTER?
	JRST	XMTXOF		;YES, GO SEND NOW
	SKIPE	LDBFLP(U)	;FILLER POINTER SETUP?
	JRST	[SCNON
		 JRST	XMTFI0]	;YES, GO SEND FILLER
	MOVSI	T1,LDLFCP	;SET TO CLEAR
	ANDCAM	T1,LDBDCH(U)	;FORCED CHARACTER PENDING
	SCNON
	JRST	XMTCHR		;NOW SEE WHAT NEEDS TO BE DONE

;HERE IF LINE IS IDLE.  CLEAR IDLE STATE AND TRY TO RETURN
; A CHARACTER.  XMTIDL WILL RESET IDLE IF NOTHING TO SEND.

XMTCIS:	MOVSI	T1,LDLIDL
	ANDCAM	T1,LDBDCH(U)	;MARK LINE AS BUSY
	PJRST	XMTCHR		;TRY TO RETURN A CHARACTER
;FALL THROUGH TO HERE TO IDLE A LINE.

XMTIDL:	HLL	U,LDBDCH(U)
	MOVSI	T1,LDLIDL	;LINE IS IDLE BIT
	IORM	T1,LDBDCH(U)	; SET IN LDB
	MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	; CLEAR
IFN FTCIMP,<			;(110)
	MOVEI	T1,LDRIMP	;(110) IMPISH?
	TDNE	T1,LDBDCH(U)	;(110) ....
	PUSHJ	P,XMTQIT##	;(110) FINISH UP OUTPUT IMP MESSAGE
>
IFN FTHDPX,<
	MOVSI	T1,L2LHDM	;CLEAR HALF DUPLEX FLAGS TOO
	ANDCAM	T1,LDBBY2(U)	; ..
>
	HRRZ	F,LDBDDB(U)	;ADDRESS OF LINKED DDB
	PUSH	P,J		;SAVE J
	JUMPE	F,XMTPSI	;JUMP IF NO DDB
	LDB	J,PJOBN##	;GET JOB NUMBER
	MOVE	T1,JBTSTS##(J)	;GET JOB STATUS
	TRNE	T1,JS.NTO	;HIBERING FOR NON-BLOCKING TTY OUTPUT?
	PUSHJ	P,WAKEJB##	;YES--WAKE HIM UP
XMTPSI:	POP	P,J		;RESTORE J

XMTDMC:	HRRZ	F,LDBDDB(U)	;IF NO DDB ALL DONE
	JUMPE	F,CPOPJ##	;IF NO DDB.
	MOVE	S,DEVIOS(F)	;IO STATUS
IFN FTCAFE&FT2741!FTNET,<
	SKIPGE	LDBDDB(U)	;ANY COMMAND?
	JRST	XMTWAK		;YES--WAIT FOR IT
	TLNE	U,LDLCOM	;AT COMMAND LEVEL?
	PUSHJ	P,UNLKBD	;YES--UNLOCK KEYBOARD
	JUMPGE	S,XMTWAK	;IF WAITING FOR OUTPUT
	TLNE	S,IOW		;WAITING FOR IO?
	PUSHJ	P,UNLKBD	;YES, THEREFORE INPUT MUST
				; UNLOCK 2741 KEYBOARD
>
XMTWAK:
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS A VTM LINE
	PJRST	VTMENQ##	;  QUEUE THE LINE SO WE SEND MORE DATA-REQUESTS
>
IFN FTMIC,<
	SKIPN	T1,LDBMIC(U)	;CONTROLLED BY MIC?
	JRST	XMTWK1		;IF NOT
IFN FTMLOG,<
	TLNE	T1,LDLLOG	;LOGGING
	PUSHJ	P,MLOGOF	;TIDY UP
> ;END IFN FTMLOG
	PUSHJ	P,MICWAK	;WAKE MIC
> ;END IFN FTMIC
XMTWK1:				;(110)
IFN FTCIMP,<			;(110)
	SKIPE	F,LDBIMP(U)	;(110) CROSSPATCHED IMP?
	PUSHJ	P,RQTIIO##	;(110) YES - REQUEST IMP/TTY PROCESSING
>;(110)
	HRRZ	F,LDBDDB(U)
	JUMPE	F,CPOPJ##
	MOVE	S,DEVIOS(F)
	TLNE	S,IOW		;IO WAIT?
	JUMPL	S,TTWAKE	;IF OUTPUT, GO WAKE JOB
	POPJ	P,		;IF INPUT, RETURN
;PACKED IMAGE MODE (PIM) TRANSMIT INTERRUPT.

XMTPIM:	SCNOFF
	SOSGE	T4,LDBTOC(U)	;COUNT DOWN
	PJRST	ZAPOU1		;IF EXHAUSTED
	LDCHKR	T3,LDBTOT(U)	;TAKE A CHARACTER, RETURN STALE CHUNKS
	SCNON			;ALLOW INTERRUPTS
	CAIN	T4,↑D50		;IF LESS THAN 50. CHARS LEFT 
	PUSHJ	P,XMTWAK	;WAKE UP THE ATTATCHED JOB
	JRST	XMTCN6		;COUNT AND RETURN THE CHARACTER

;HERE WHEN THE OUTPUT STREAM COUNT IS EXHAUSTED.  RESET IT TO ZERO
;AND SET THE LINE IDLE.  COME HERE ONLY WITH SCANNER INTERLOCK SET.

ZAPOU1:	SETZM	LDBTOC(U)	;COUNT IS PROBABLY NEGATIVE NOW
	MOVE	T2,LDBTOT(U)	;$MAKE SURE PUTTER MATCHES TAKER
	CAME	T2,LDBTOP(U)	;$MAKE SURE BOTH POINTERS MATCH
	PUSHJ	P,RCCSTP	;$NO, DIE NOW
	SCNON			;ALLOW INTERRUPTS AGAIN
	PJRST	XMTIDL		;IDLE THE LINE


;ROUTINE TO ALLOW SCANNER INTERRUPTS AGAIN AND SKIP RETURN

SONPJ1::AOS	0(P)		;SKIP RETURN

SONPPJ::SCNON			;ALLOW SCANNER INTERRUPTS
	POPJ	P,		;AND RETURN
;HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBMIC IS NON-ZERO

XMTMIC:
IFN FTMIC,<			;IF MIC
IFN FTMLOG,<
	MOVE	T2,LDBMIC(U)
	TLNE	T2,LDLLOG	;HAS HE ASKED FOR LOG
	SKIPE	LDBLOT(U)	;HAS HE GOT A LOG TAKER
	JRST	MICLG3
	MOVE	T2,LDBTOT(U)	;MAKE COPY OF TAKER
	MOVEM	T2,LDBLOT(U)
MICLG3:
> ;END OF FTMLOG CONDITIONAL
	PUSHJ	P,HPOS		;GET HORZONTAL POSITION ON LINE
	JUMPN	T2,XMTOK	;IN COLUMN 1?
	SKIPE	T2,LDBMIC(U)	;IS HE RUNNING MIC OR
	TLNN	T2,LDLRSP!LDLRSY	;WANTS RESPONSE FEATURE
	JRST	XMTOK1		;NO - MUST NOT INTERFERE
	TLNE	T2,LDLERC	;HAS HE HAD ERROR?
	TLNE	T2,LDLMCC	;AND NOT ↑C
	JRST	XMTOK1		;NO - IGNORE
	SKIPN	LDBTOC(U)	;IS THERE A CHARACTER WAITING?
	JRST	XMTOK1		;NO, IGNORE
	MOVE	T4,LDBTOT(U)	;COPY OF OUTPUT TAKER
	LDCHK	T3,T4		;PREVIEW NEXT CHARACTER
	LDB	T2,LDP.ER	;GET ERROR CHAR
	JUMPE	T2,XMTOK	;MUST BE ONE
	ANDI	T3,177		;JUST 7 BITS
	CAIE	T3,"?"		;IS IT A "?"
	CAMN	T3,T2		; OR THE ERROR CHARACTER
	CAIA			;YES, HANDLE MIC'S RESPONSE
	JRST	XMTOK		;NO IGNORE
	MOVSI	T2,LDLRSY!LDLCHK	;SET THE SYNC
	IORB	T2,LDBMIC(U)
	TLNN	T2,LDLRSP	;BEEN THIS WAY BEFORE
	JRST	XMTECH		;YES JUST DO ECHOING
	HRRZ	F,LDBDDB(U)
	JUMPE	F,XMTECH	;NO ATTACHED DDB
	MOVE	S,DEVIOS(F)
	TLNN	S,IOW		;IN IO WAIT?
	JRST	XMTECH		;NO FORGET IT
	MOVSI	T2,LDLRSP
	ANDCAM	T2,LDBMIC(U)	;SAY SYNC
	PUSHJ	P,MICWAK
	JRST	XMTECH		;AND PUT THE PLUG IN

XMTOK:	MOVE	T2,LDBMIC(U)	;GET MIC BITS
XMTOK1:	TLNE	T2,LDLRSY	;WAITING FOR MIC TO TAKE RESPONCE
	JRST	XMTECH		;YES, KEEP THE PLUG IN

IFN FTMLOG,<
	SKIPN	LDBLOT(U)	;ARE WE LOGGING THIS?
	JRST	XMTCH2		;NO, GO TAKE CHARACTER NORMALLY
	SCNOFF			;NO INTERRUPTS
	SOSGE	LDBTOC(U)	;DECREMENT COUNT OF CHARACTERS AND TEST
	JRST	ZAPBUF		;IF OUTPUT STREAM NOW EMPTY
	LDCHK	T3,LDBTOT(U)	;TAKE A CHARACTER OUT OF THE STREAM
	AOS	LDBLOC(U)	;COUNT UP THE NUMBER TO BE LOGGED
	JRST	XMTCH3		; AND JOIN PROCESSING
> ;END IFN FTMLOG
> ;END OF IF MIC

;ENTER HERE WITH SCNOFF TO CLEAR LDBTOC AND CHECK FOR ECHO

ZAPBUF:	SETZM	LDBTOC(U)	;ZERO COUNT
	MOVE	T1,LDBTOP(U)	;GET PUTTER
	CAME	T1,LDBTOT(U)	;MUST MATCH TAKER
	PUSHJ	P,RCCSTP	; OOPS, SOMETHING IS WRONG
	SCNON			;ALLOW INTERRUPTS
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS A VTM LINE,
	PUSHJ	P,VTMENQ##	;  WE MUST BE SURE TO SEND DATA-REQUESTS
>				;  NOW THAT WE'RE OUT OF DATA.
	JRST	XMTECH		;LOOK FOR SOMETHING TO ECHO
;HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBXNP IS NON-ZERO.
;LDBXNP IS A NINE-BIT BYTE POINTER TO FORCED CHARACTERS SUCH AS
; XOFF AND BELL.

XMTXOF:	SCNON			;ALLOW INTERRUPTS
	ILDB	T3,LDBXNP(U)	;GET A CHARACTER.
	JUMPN	T3,XMTCNT	;COUNT THE CHARACTER AND RETURN
	SETZM	LDBXNP(U)	;REACHED END. CLEAR POINTER
	SKIPN	LDBFLP(U)	;IS THERE A FILLER POINTER?
	JRST	XMTCHR		;NO, SEE IF ANY OUTPUT STREAM
				;YES, FALL INTO XMTFIL

;HERE ON A TRANSMIT-DONE INTERRUPT WHEN LDBFLP IS NON-ZERO.
;LDBFLP IS A NINE-BIT BYTE POINTER TO FILLER CHARACTERS, OR
; TO FREE CRLF'S OR TAB SIMULATIONS.

XMTFIL:
XMTFI0:	HLL	U,LDBDCH(U)	;REFRESH LEFT HALF OF U
	ILDB	T3,LDBFLP(U)	;GET A FILLER CHARACTER
	JUMPN	T3,XMTFI1	;IF NOT AT END, SEND IT AND DISMISS
	LDB	T1,LDPFCT	;FILL REPEAT COUNTER
	JUMPE	T1,XMTFI3	;JUMP IF NO REPEAT COUNT
	LDB	T3,LDPSVC	;SAVED CHARACTER
	MOVSI	T1,LDLUAW	;CONTROL W BIT
	TDNE	T1,LDBTTW(U)	;PROCESSING CONTROL W?
	JUMPN	T3,[MOVEI T2,1	;YES, JUMP IF HARD COPY TERMINAL
		    PUSHJ P,SETFLP ;STORE DUMMY FILLER POINTER
;		    SETZ T1,	;ZERO SAVED CHARACTER
		    JRST XMTFI4];ECHO CHARACTER AND RETURN
	ANDI	T3,177		;JUST 7 BITS
	TDNE	T1,LDBTTW(U)	;SKIP IF NOT CONTROL W
	SKIPA	T1,CHTABL+"W"-100 ;GET CONTROL W DISPATCH
	MOVE	T1,CHTABL(T3)	;GET CHARACTER DISPATCH
	PUSHJ	P,(T1)		;DISPATCH TO CHARACTER HANDLING ROUTINE
	JRST	XMTFI0		;CHECK FOR MORE FILL
XMTFI3:	MOVSI	T1,LPLSAP	;WAITING TO DO A
	TDNE	T1,LDBPAG(U)	;SEND ALL?
	JRST	[SOSGE	SNDCTR##	;COUNT DOWN SEND ALL COUNT
		SETZM	SNDCTR##	;BUT DON'T LET IT GO NEGATIVE!
		ANDCAM	T1,LDBPAG(U)	;YES -- CLEAR BIT
		MOVE	T1,SNDPTR##	;SET UP POINTER
		MOVEM	T1,LDBFLP(U)	;STORE IN LDB
		JRST	XMTFI0]		;TYPE THE STRING
	SETZB	T1,LDBFLP(U)	;END. CLEAR THE BYTE POINTER AND T1
	LDB	T3,LDPSVC	;SEE IF ANY SAVED CHARACTER
	JUMPE	T3,XMTCHR	;IF NOT, RETURN TO XMTCHR AND TRY AGAIN
XMTFI4:	TLNE	U,LDLSSO	;A PAGE BREAK PENDING?
	JRST	[MOVE T2,FLLDMP	;YES, GET DUMMY FILLER POINTER
		 PUSHJ P,SETFLP	;AND SET IT IN THE LDB
		 JRST XMTIDL]	;MARK THE LINE AS IDLE
	DPB	T1,LDPSVC	;CLEAR THE SAVED CHAR BYTE
	TRNE	T3,400		;IF TAB SIMULATION
	JRST	XMTFI2		; WHO KNOWS
	ANDI	T3,177		;JUST CHARACTER
	MOVE	T1,CHTABL(T3)	;CHARACTER DESCRIPTOR BITS
	TRO	T3,200		;SO IT WILL ECHO
	JRST	XMTEC4		;GO TYPE IT

XMTFI2:	MOVE	T1,LDBDCH(U)
	TDNN	T1,[LDLLCP+LDLNEC,,LDRHLF]
	SKIPE	LDBTOC(U)	;WAS THAT CHAR FOR INPUT OR OUTPUT?
	JRST	XMTCH4		;OUTPUT. GO SEND IT WITH FILLERS
	IORI	T3,200		;SET THE "NEED TO ECHO THIS CHAR" BIT
	JRST	XMTEC6		;AND GO ECHO THE POOR THING

XMTFI1:	CAIE	T3,FLLFLG	;IS THIS A FLAG OR A CHARACTER?
	PJRST	XMTCNT		;COUNT CHARACTER AND RETURN IT
	PUSHJ	P,SETFLC	;GET CORRECT FILL CLASS
	MOVE	T3,FLLCRP(T2)	;GET RIGHT CRLF POINTER
	MOVEM	T3,LDBFLP(U)	;PLACE IN FILLER POINTER
	PUSHJ	P,SCNBOL	;MAKE SURE AT LOGICAL BOL
	JRST	XMTFI0		;AND GO TYPE FROM IT.
;HERE WHEN BUFFERED AND FILLER OUTPUT DONE, AND LDBECT IS NON-ZERO
;NEED TO ECHO A CHARACTER THAT HAS BEEN TYPED IN.

XMTECH:
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS AN ACTIVE VTM LINE
	JRST	XMTIDL		;  DON'T TRY TO ECHO ANYTHING.
>				;  THE CHUNKS ARE HORRIBLY MESSED UP.
	HLL	U,LDBDCH(U)
	HRRZ	T1,LDBBYT(U)	;GET WORD CONTAINING DEFERRED ECHO BITS
ifn ftcimp,<			;(110)
	SKIPE	LDBIMP(U)	;(110)Always echo immediately if xpatched
	JRST	XMTEIP		;(110)
>;(110)
	TRNE	T1,L1RDEM	;DEFERRED ECHO MODE SELECTED?
	TRNE	T1,L1RDEL!L1RDEC; HAS AN INPUT REQUEST BEEN MADE YET?
	CAIA			;EITHER INPUT WAIT OR IMMEDIATE ECHO
	JRST	XMTIDL		;DEFERRED AND NOT REQUESTED YET
IFN FTCIMP,<XMTEIP:>		;(110)
	SCNOFF			;DISALLOW INTERRUPTS
	SOSGE	LDBECC(U)	;ANY LEFT TO ECHO?
	JRST	ZAPECH		;NO, FINISH UP
	LDCHK	T3,LDBECT(U)	;TAKE CHARACTER FROM INPUT, SAVE CHUNKS
	AOS	T2,LDBTIC(U)	;COUNT THE INPUT CHARACTERS
	SCNON			;ALLOW INTERRUPTS
IFN FTRSP!FTACCT,<AOS %SCNEI>	;COUNT CHARACTERS ECHOED
	MOVEI	T4,L1RDEC	;CHARACTER REQUEST BIT
	PUSHJ	P,SPCHEK	;SEE IF IT'S SPECIAL.
	  JRST XMTEC1		;IT'S NOT.
	SKIPN	LDBIMP(U)	;(110) IF CROSSPATCHED, DON'T PROCESS AS A BREAK
	TLNN	T1,CHBRK	;YES. IS IT A BREAK CHAR?
	JRST	XMTEC1		;NOT A BREAK
	MOVEI	T4,L1RDEC!L1RDEL;GET LINE REQUESTED BIT
	AOS	LDBBKC(U)	;COUNT LINES IN THE LDB
IFN FTRSP!FTACCT,<AOS LDBBCT(U)>;COUNT BREAK CHARACTERS INPUT
XMTEC1:	ANDCAM	T4,LDBBYT(U)	;CLEAR, SINCE WE ECHOED A CHARACTER
	PUSH	P,T1		;SAVE CHARACTER BITS
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) ALWAYS BREAK ON XPATCHED TO AN IMP
>				;(110)
	TLNE	U,LDLBKA+LDLIMI	;BREAK ON ALL CHARACTERS?
	JRST	[PUSHJ	P,RCVWKQ	;YES, WAKE JOB
	JRST	XMTEC2]		;AVOID EXTRA WAKE IF BREAK TOO
	CAIG	T2,↑D72		;ARE THERE OVER 72. OF THEM?
	TLNE	T1,CHBRK	;OR IS IT A BREAK CHARACTER?
	PUSHJ	P,ECHBRK	;YES. WAKE THE JOB, IF ANY
XMTEC2:	POP	P,T1		;RESTORE CHARACTER BITS INTO T1

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

XMTEC3:
IFN FTMIC,<
	SKIPE	T2,LDBMIC(U)	;MIC IN CONTROL OF THIS LINE?
	TLNN	T2,LDLSIL	;YES, IS IT .SILENCED?
	CAIA			;NOT .SILENCED OR NOT MIC
	JRST	XMTCHR		;.SILENCED, EAT THE CHAR
> ;END IFN FTMIC
	TRNN	T3,400		;IMAGE?
	TLNE	U,LDLNEC	;NON-ECHOING?
	JRST	XMTEC6		;YES, LEAVE ALONE
	MOVE	T2,LDBDCH(U)	;GET LINE CHARACTERISTICS
	TDNN	T2,[XWD LDLLCP,LDRHLF]	;LOCAL COPY?
	JRST	XMTEC4		;NO, COUNT UP NORMAL CHARACTER
	MOVEI	T2,L2RXON	;PAPER TAPE?
	TDNE	T2,LDBBY2(U)	;...
	JRST	XMTEC6		;YES.  NO FILLERS, ELSE GARBLE.
XMTEC4:	TLNE	T1,CHSPO	;SPECIAL CHARACTER OF SOME FLAVOR?
	JRST	XMTEC5		;YES, MORE EXTENSIVE HANDLING REQUIRED
	AOSG	LDBHPS(U)	;NORMAL CHARACTER, ECHO ONE CHAR POSITION
	JRST	XMTEC6		;GO DO IT
	SOS	LDBHPS(U)	;UNDO AOSG (ADJHP WILL RE-DO IT)
XMTEC5:
IFN FTTBLK,<
	MOVSI	T2,LPLBLK	;THE SUPPRESS-BLANK-LINES BIT
	TDNE	T2,LDBPAG(U)	;"TTY NO BLANK" SET?
	PUSHJ	P,BLSUPI	;YES, NOTE PASSING <LF>S ET AL
> ;IFN FTTBLK
	PUSHJ	P,ADJHP		;ADJUST CARRIAGE POSITION FOR ECHOED CHARACTER
IFN FTCIMP,<			;(110)
	SKIPE	LDBIMP(U)	;(110) IF CROSSPATCHED, CLEAR IMAGE BIT FOR
	ANDI	T3,377		;(110)  ECHOING
>				;(110)
	PUSHJ	P,SETFLI	;SET FILLERS FOR ECHOING
IFE FTLINK,<			;(111)
	  JRST XMTFI0		;OUTPUT FROM FILLER POSITION.
>				;(111)
IFN FTLINK,<			;(111)
	  JRST	[PUSHJ	P,CHKLKF## ;(111) SEND FILLER TO ANY LINKS
		 JRST	XMTFI0]	   ;(111) AND OUTPUT FROM FILL POSITION
>
;(270)IFN FTCIMP,<			;(110)
;(270)	CAIA			;(110) TURKEY DOUBLE SKIP CAN COME FROM SETFLI
;(270)				;(110) TALK TO RUTGERS ABOUT THIS ONE
;(270)	JRST	XMTCHR		;(110) DOUBLE SKIP MEANS NO ECHO AT ALL
;(270)>				;(110)
XMTEC6:
ifn FTCIMP,<	;(270) check to see if we REALLY want to echo this
	skipn	ldbimp(u)	;(270) cross patched?
	  jrst	XMTNCP		;(270) no.  don't check
	move	t1,t3		;(270) copy character
	andi	t1,177		;(270) JUST the character
	move	t1,chtabl(t1)	;(270) get the bits for it.
	TLNE	T1,CHALT	;(270) IF ALT OR ↑X SUPPRESS ECHO 
	  jrst	XMTChr		;(270) go get next character
XMTNCP:	; come here if not cross patched
> ;(270) end of ifn FTCIMP
IFN FTMIC,<
	SKIPE	T1,LDBMIC(U)	;RUNNING MIC?
	TLNE	T1,LDLMCB	;IN MIC BREAK?
	CAIA			;IN MIC BREAK, DO NORMAL ECHO CHECKING
	JRST	XMTEC8		;NO, MIC CHARACTERS ALWAYS ECHO
> ;END IFN FTMIC
	MOVE	T1,LDBDCH(U)	;GET LEFT AND RIGHT HALF BITS
	TDNE	T1,[XWD LDLLCP,LDRHLF!LDR2741]	;EITHER TYPE OF LOCAL COPY?
	JRST	XMTCHR		;YES. DO NOT ECHO THE CHARACTER
IFN FTNET,<
	TRNN	T3,600		;IF IMAGE, OR NOT ECHOED BY REMOTE
	JRST	XMTCHR		;IF NOT VTM, DON'T ECHO, IF VTM, MUST ECHO HERE
> ;END IFN FTNET		;ECHO THE CHARACTER NOW
XMTEC8:	TLNN	U,LDLCOM	;CHARACTER ITSELF SHOULD BE ECHOED
	TLNN	U,LDLNEC	;UNLESS USER LEVEL AND HE SAID NO
	JRST	XMTCN4		;RETURN CHARACTER
	JRST	XMTCHR		;NO, STEP TO NEXT CHARACTER
ZAPECH:	SETZM	LDBECC(U)	;FIX UP
	MOVE	T2,LDBTIP(U)	;$MESSED UP
	CAME	T2,LDBECT(U)	;$CHECK POINTERS
	PUSHJ	P,RCCSTP	;$SOMETHING IS WRONG
	SCNON			;ALLOW INTERRUPTS
	JRST	XMTIDL

ECHBRK:	PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  PJRST RCVWAK		;NO. WAKE JOB IF ANY.
	PJRST	COMSET		;YES. SET COMMAND REQUEST.

RCVWKQ:	PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  PJRST	RCVWAK		;NO. WAKE JOB.
	POPJ	P,0		;YES. DON'T MAKE COMMAND FOR LDLBKA

IFE FTHDPX,<
XMTHDX==CPOPJ##
>
IFN FTHDPX,<
XMTHDX:	JUMPL	T1,XMTHCH	;IF LINE IS IDLE, JUST TREAT NORMALLY
	MOVSI	T1,L2LHD1	;FLAG THAT XMT DONE HAPPENED
	IORB	T1,LDBBY2(U)	; ..
	TLNN	T1,L2LHD2	;HAS REC INT OCCURRED ALSO?
	POPJ	P,		;RETURN
	JRST	RHDERQ		;YES. GO SEE IF ERROR IN ECHO
>

;ROUTINE TO QUEUE FOR A CHANGE HARDWARE PARAMETER MESSAGE

SETCHP::MOVEI	T1,L1RCHP
	IORM	T1,LDBBYT(U)	;MARK THAT ISRCHP MUST BE CALLED
	PJRST	TOPOKE		;ADD TO QUEUE

CLRIRM::MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	;CLEAR IN LDB
	POPJ	P,		;RETURN
TOREQ::	MOVSI	T1,LDLIDL
	IORM	T1,LDBDCH(U)
;;	PJRST	TOPOKE

;ROUTINE TO PLACE AN LDB INTO THE START OUTPUT QUEUE.  SCANNED
;AT CLOCK LEVEL ONCE PER TICK.
;CALL
;	MOVEI	U,LDB ADDRESS
;	PUSHJ	P,TOPOKE
;	<RETURN HERE ALWAYS>
;USES T1,T2

TOPOKE::MOVEI	T1,LDRPTY	;PTY BIT
	TDNE	T1,LDBDCH(U)	;IS THIS A PTY?
	PJRST	PTYPE##		;YES, DON'T QUEUE OUTPUT
	MOVSI	T1,LPLPOK	;OUTPUT BEING STARTED BIT
	TDNE	T1,LDBPAG(U)	;CHECK BEFORE WE GET THE INTERLOCK
	POPJ	P,		;  JUST FOR EFFICIENCY'S SAKE
IFN FT.DTF,<			;(107)
	PUSH	P,T1		;(107)
	PUSHJ	P,DSCTOR	;(107) RESET DIAL-UP TIMEOUT FIELD
	POP	P,T1		;(107)
>;(107)
	SCNOFF			;NO INTERRUPTS
	TDNE	T1,LDBPAG(U)	;...
	JRST	SONPPJ		;YES, BY SOMEONE ELSE
	IORM	T1,LDBPAG(U)	;NO.  INDICATE LDB IS GOING INTO THE QUEUE
	HLRZ	T1,LDBQUE(U)	;GET THE QUEUE HEADER ADDRESS
	HLRZ	T2,0(T1)	;LAST ENTRY OF CURRENT QUEUE
	SKIPN	T2		;NON-NULL QUEUE?
	MOVEI	T2,-LDBQUE(T1)	;POINT TO QUEUE HEADER WORD
	HRRM	U,LDBQUE(T2)	;STORE ADDRESS OF ARGUMENT LDB AT END
	HRLM	U,0(T1)		;UPDATE LATEST ENTRY
	HLLZS	LDBQUE(U)	;MAKE SURE LIST TERMINATESS
	JRST	SONPPJ		;ALLOW INTERRUPTS AND RETURN


;ROUTINE TO TAKE AN LDB OUT OF THE 'START OUTPUT' QUEUE
;CALLED FROM DEVICE DRIVERS TO FIND LINES THAT ARE WAITING TO DO OUTPUT.
;CALL
;	MOVE	T1,ADDRESS OF LIST HEADER
;	PUSHJ	P,TOTAKE
;	  <IF EMPTY QUEUE>
;	<LDB ADDRESS IN U>
;
;USES T2.

TOTAKE::SKIPN	0(T1)		;IF QUEUE IS EMPTY NOW
	POPJ	P,		; AVOID INTERLOCK
	SCNOFF
TOTAK1:	MOVSI	T2,LPLPOK	;HAS OUTPUT BEEN STARTED?
	HRRZ	U,0(T1)		;POINT TO FIRST LDB IN LIST
	JUMPE	U,SONPPJ	;IF NONE
	ANDCAM	T2,LDBPAG(U)	;CLEAR 'IN QUEUE' BIT
	HRRZ	T2,LDBQUE(U)	;NEXT LDB IN LIST
	SKIPN	T2		;END OF LIST?
	SETZM	0(T1)		;YES, CLEAR HEADER
	HRRM	T2,0(T1)	;ADVANCE LIST
	SKIPGE	LDBDCH(U)	;IS OUTPUT ALREADY GOING?
	JRST	SONPJ1		;LINE IDLE, GIVE GOOD RETURN
	MOVEI	T2,L1RCHP
	TDNN	T2,LDBBYT(U)	;NEED TO SEND CHANGE PARAMETER MESSAGE?
	JRST	TOTAK1		;NO, SKIP TO NEXT
	JRST	SONPJ1		;YES, RETURN THE LINE
	SUBTTL	RECEIVE INTERRUPT ROUTINE

;HERE FROM DEVICE-DEPENDENT INTERRUPT ROUTINE ON A RECEIVE INTERRUPT.
;AT THIS POINT, T3(28-35) HAS RECEIVED CHARACTER, U HAS PHYSICAL LINE #
;AS INDEX INTO LINTAB

RECINT::MOVE	U,LINTAB##(U)	;LOAD LDB ADDRESS
IFN FTCIMP,<			;[BCH]	
	SKIPE	LDBIMP(U)	;[BCH] IF XPATCHED,
	ANDI	T3,377		;[BCH] THEN USE ONLY 8 BITS OF CHARACTER
RecImp::	;(271) come here to handle stuff coming over the IMP
>;[BCH]
RECPTY:	MOVEI	T2,L1RMIF	;MIC INTERLOCK FLAG
	SCNOFF			;LOCK OTHER CPU
	TDNE	T2,LDBBYT(U)	;IS MIC TYPING ON THIS LINE?
	JRST	SONPPJ		;YES, IGNORE CHAR
	IORM	T2,LDBBYT(U)	;SET THE INTERLOCK BIT
	SCNON			;ALLOW INTERRUPTS
	PUSHJ	P,RECINU	;PROCESS THE INTERRUPT
	MOVEI	T2,L1RMIF	;GET THIS BIT AGAIN
	ANDCAM	T2,LDBBYT(U)	;CLEAR INTERLOCK
IFN FTRSP!FTACCT,<		;IF COUNTING CHARACTERS
	AOS	LDBICT(U)	;COUNT INPUT CHARACTERS THIS LINE
	AOS	%SCNRI		;AND INPUT CHARACTERS FOR THE SYSTEM
> ;END IFN FTRSP!FTACCT
	POPJ	P,		; AND DISMISS THE INTERRUPT

RECINU:
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) LEAVE IMAGE BIT ALONE IF XPATCHED
>;(110)
	ANDI	T3,377		;JUST 8 BITS OF CHARACTER.
				; CLEAR ANY DEVICE DEPENDENT BITS
IFN FTNET,<			;IF NETWORK
	SKIPGE	LDBREM(U)	;IF THIS IS AN ACTIVE VTM LINE,
	JRST	VTMREC##	;  GO HANDLE NVT CHARS SPECIAL
>
	MOVSI	T1,L1LOFL	;PUT TERMINAL ON LINE
	ANDCAM	T1,LDBOFL(U)	;SINCE SOMEONE IS THERE
IFN FTMODM,<
	LDB	T1,LDPDSC	;GET DATASET TABLE INDEX
	MOVE	T1,DSCTAB##(T1)	;GET DATASET DATA
	TLNE	T1,DSCBLI	;WANT TO IGNORE INTERRUPTS?
	JRST	[PUSHJ	P,CHKDSD	;(1) IS IT A DATASET LINE?
	IFE FT.DTF,<			;(107) 
		JRST	RECIN0		;NO.  PROCESS CHARACTER
		POPJ	P,		;(107) YES.  DISCARD CHARACTER
	>				;(107)
	IFN FT.DTF,<			;(107)
		SKIPA			;(107) NO. PROCESS CHARACTER
		POPJ	P,		;(107) YES.  DISCARD CHARACTER
		PUSHJ	P,DSCTOR	;(107) RESET ACTIVITY CHECKING
					;(107) TIME-OUT FIELD
		JRST	RECIN0>]		;(107) PROCESS FIELD
> ;END OF IFN FTMODM

	MOVEI	T1,ST.NRT	;THE STAND ALONE (NO REMOTE) BIT
	TDNE	T1,STATES##	;IS THE SYSTEM STAND ALONE?
	JRST	[HRR	T1,LDBDCH(U)	;YES, GET CHARACTERISTICS
		TRNN	T1,LDRDSR	;IS THE TERMINAL REMOTE/DATASET?
		JRST	RECIN0		;NO, LOCAL, ALLOW IT
		HRRZ	T1,LDBDDB(U)	;REMOTE, BUT IS IT ALREADY IN USE?
		JUMPN	T1,RECIN0	;YES, ALLOW IT TO CONTINUE TO WORK
		JRST	BEATIT]		;NO, DUMP IT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

RECIN0:
IFN FTTRACK,<DPB T3,LDPRCS>	;SAVE RECEIVED CHARACTER FOR DEBUG
IFN FTHDPX,<
	MOVE	T1,LDBDCH(U)	;SEE IF IT IS HALF DUPLEX
	TRNE	T1,LDRHLF	; ..
	JRST	RECHDX		;YES. SPECIAL HANDLING
> ;END IFN FTHDPX
RECIN1:	HLL	U,LDBDCH(U)	;CARRY DEVICE BITS IN LH.
	TLNE	U,LDLPIM	;PIM MODE?
	JRST	REPIM		;YES, GO TO PIM CODE
	SKIPG	TTFREN##	;ANY SPACE FOR CHARACTERS?
	JRST	RCHLT1		;NO. SHUT IT DOWN.
	TLNN	U,LDLIMI	;IN IMAGE INPUT MODE?
	JRST	RECIN2		;NO.
IFN FTCIMP,<			;(110)
RECNXI:>			;(110) LABEL ADDED
	MOVEI	T1,IMGTIM	;YES. RESET TIMEOUT FIELD TO MAX
	DPB	T1,LDPTIM	; ..
	TRO	T3,400		;MARK IN NINTH BIT.
	JRST	RECINA		;AND GO STORE IN BUFFER. NO BREAK.
RECIN2:	SKIPG	LDBTIC(U)	;FIRST INPUT CHARACTER ON LINE
	JRST	[PUSHJ	P,HPOS	;YES, GET CURRENT HORIZONTAL POSITION
		DPB	T2,PRPOS;REMEMBER IT FOR ERASING TABS
		JRST	.+1]
IFN FTCIMP,<			;(110)
	SKIPN	F,LDBIMP(U)	;(110) CROSSPATCHED TO IMP?
	JRST	RECQRT		;(110) NO.
	TRNE	T3,400		;(110) YES - SPECIAL CHAR HANDLING?
	JRST	RECINA		;(110) YES - STORE AS IS
	ANDI	T3,177		;(110) NO, STRIP PARITY
;(270) finally make this a routine so PTYSER can call it
;(270)RECNXQ:	SKIPE	T1,LDBQUO(U)	;(110) ANY QUOTES OR ESCAPES ENABLED?
;(270)	JRST	RECQUO		;(110) YES - GO HANDLE THEM
	pushj	p,RecQuo	;(270) check for network quotes or whatever.
	  popj	p,		;(270) was something and we sent it.
	;(270)	returns here if it wasn't anything the network cares about.
RECQRT:>			;(110)
	PUSHJ	P,SPCHEK	;SEE IF IT'S SPECIAL. SET T1 UP.
	  JRST RECIN3		;NON-SPECIAL. SEE IF LOWER CASE
IFN FTCIMP,<			;(110)
	TLNN	T1,CHXPIH	;(110) SPECIAL EVEN IF CROSSPATCHED?
	JUMPN	F,RECI2A	;(110) JUMP IF CROSSPATCHED (F SET UP BEFORE)
>;(110)  END IFN FTCIMP
	TLNE	T1,CHRIA	;DOES THIS CHAR NEED SPECIAL RCV HANDLING?
	JRST	0(T1)		;YES. GO TO IT.
				;NO. FALL INTO ORDINARY CHAR HANDLER
IFN FTCIMP,<			;(110)
	JRST	RECINA		;(110) JUMP AROUND IMP CODE
RECI2A:	TLZ	T1,CHBRK!CHCNC	;(110) SUPPRESS SPECIAL HANDLING BECAUSE CROSSPATCHED
	IORI	T3,400		;(110) SET IMAGE BIT
>;(110) END FTCIMP
;HERE WITH T1=CHARACTER BITS (LH=0 IF NONE), T3=CHARACTER

IFE FTWATCH,<RICT:>
RECINA:	TRNE	T3,400		;IF THIS IS AN IMAGE MODE CHAR,
	JRST	RECINB		; DON'T TOUCH THE ECHO/PARITY BIT
	TRO	T3,200		;FIRST, ASSUME THAT REMOTE DIDN'T ECHO CHAR
IFN FTNET,<
	MOVE	T2,LDBDCH(U)	;GET THE CHARACTERISTICS, AND
	TRNN	T2,LDRREM	;  IF THIS LINE IS A LOCAL LINE (NOT REMOTE)
	JRST	RECINB		;  THEN THE REMOTE DIDN'T ECHO THE CHAR.
	MOVEI	T2,STY.DE	;GET THE "REMOTE LOCAL ECHO" BIT
	TDNN	T2,LDBREM(U)	; AND IF THE REMOTE IS ECHOING THE CHARS,
	TRZ	T3,200		; THEN CLEAR THE "NEEDS ECHOING" BIT
>
RECINB:	MOVE	T2,LDBTIC(U)	;COUNT CHARACTERS LINE HAS INPUT
	ADD	T2,LDBECC(U)	;PLUS LEFT TO ECHO
	PUSH	P,T1		;SAVE CHARACTER BITS
	CAILE	T2,↑D120	;TIME TO WARN HIM?
	JRST	RWARN		;YES.  GO SEND XOFF.
RWARNX:	SCNOFF
	STCHK	T3,LDBTIP(U)	;STORE CHARACTER
	AOS	LDBECC(U)	;COUNT CHARACTER TO ECHO
	POP	P,T1		;RESTORE T1
IFN FTCIMP,<			;XPATCHED TTYS DON'T HAVE BREAK CHARACTERS
	SKIPE	LDBIMP(U)	;(110)
	JRST	[SCNON		;(110) NO MORE NON-SENSE IF XPATCHED
		 SETZ	T2,	;(110) CLEAR ↑C AND DEL BITS
		 TLO	T2,L2LCCS!L2LDEL ;(110)
		 JRST	RECINI]	;(110)
>;(110)
	TLNE	T1,CHBRK	;BREAK CHARACTER?
	PUSHJ	P,SETBKU	;YES, NOTE PLACE
	SCNON
IFN FTMIC,<			;IF MIC
	SKIPE	LDBMIC(U)	;IS HE RUNNING MIC?
	PUSHJ	P,MICECH	;YES - SEE IF <CR> TYPED
> ;END OF IF MIC
	MOVE	S,FLLBSP	;PREPARE BACKSLASH POINTER
	MOVSI	T2,L2LDEL	;WAS PREVIOUS CHAR A RUBOUT?
	TDNN	T2,LDBBY2(U)	; ..
	JRST	RECIN6		;NO
	MOVEM	S,LDBFLP(U)	;YES. STORE BACKSLASH FILLER PTR
	MOVSI	S,LDLFCP	;FORCING FLAG
	IORM	S,LDBDCH(U)	;FLAG FOR XMTCHR
IFN FTLINK,<			;(111)
	PUSH	P,T1		;(111) PRESERVE AGAINST RAVAGES OF TIME
	PUSH	P,T2		;(111) DITTO
	PUSHJ	P,CHKLKF##	;(111) RAVAGES - CHECK FOR FILL LINKS
	POP	P,T2		;(111) UNPRESERVE
	POP	P,T1		;(111) OTTID
>;(111) END IFN FTLINK
	AOS	LDBHPS(U)	; AND COUNT POSITION OF BACKSLASHES
RECIN6:	TLNN	T1,CHCNC	;IS THIS CHARACTER A CONTROL C?
	TLO	T2,L2LCCS	;NO. PREPARE TO CLEAR L2LCCS BIT
IFN FTCIMP,<RECINI:>		;(110)
	ANDCAM	T2,LDBBY2(U)	;CLEAR DELETE AND CONTROL C FLAGS
IFN FTLINK,<			;(111)
	TLNN	T1,CHUAE	;(111) ECHO AS ↑X?
	TLNE	U,LDLNEC	;(111) OR NOT ECHOING AT ALL?
	JRST	RECLN1		;(111) YES - DON'T ECHO TO LINKS EITHER
	MOVSI	T2,LNKECH	;(111) MARK AS SENDING ECHO TO LINKS
	IORM	T2,LDBLNK(U)	;(111) ....
	PUSH	P,T1		;(111) KEEP IT AROUND
	PUSHJ	P,CHKLNK##	;(111) SEND ECHO TO ANY OPEN LINKS
	POP	P,T1		;(111)
RECLN1:> ;(111) END FTLINK
	PJRST	TOPOKE		;QUE TO GET ECHO STARTED
RECIN3:	LDB	T2,[POINT 7,T3,35]	;GET SEVEN BITS OF CHARACTER
	CAILE	T2,140		;LOWER CASE LETTER?
	TLNN	U,LDLLCT	;YES. WANT TO BE UPPER?
IFE FTCIMP,<			;(110)
	SKIPA
>				;(110)
IFN FTCIMP,<			;(110)
	JRST	RECI3A		;(110) NO UPPER
	LDB	T2,LDPSFT	;(110) ANY SHIFT CHAR DEFINED?
	JUMPN	T2,RECI3A	;(110) YES - BYPASS
	SKIPE	LDBIMP(U)	;(110) CROSSPATCHED?
	TRCA	T3,40		;(110) YES - DON'T MESS WITH PARITY
>;(110) END FTCIMP
	TRC	T3,240		;YES. MAKE UPPER, CORRECT PARITY
IFN FTCIMP,<			;(110)
RECI3A:				;(110)
	SKIPE	LDBIMP(U)	;(110) DON'T DO AUTO CRLF IF XPATCHED
	JRST	RECINA		;(110)
>
	LDB	T4,LDPACR	;GET AUTO CRLF BYTE
	JUMPE	T4,RECINA	;IGNORE IF ZERO
	TLNN	U,LDLCOM
	TRNE	T3,137		;SEE IF SPACE
	JRST	RECINA		;NO--FORGET IT
	PUSHJ	P,HPOS		;GET POSITION ON LINE
	SUBI	T2,(T4)		;SEE IF ROOM
	JUMPL	T2,RECINA	;JUMP IF YES
	MOVEI	T3,215		;ELSE CONVERT TO
	JRST	RECIN2		;CR


;ROUTINE TO REMEMBER THE BREAK CHARACTER POSITION IN LDBBKU

SETBKU:	MOVE	T2,LDBTIP(U)	;LOCATION OF INPUT PUTTER
	MOVEM	T2,LDBBKU(U)	;SAVE IT
	POPJ	P,
IFN FTHDPX,<

RECHDX:	JUMPGE	T1,RECIN1	;IF NOT OUTPUTTING, TREAT AS KEYBOARD FLAG
	MOVE	T1,LDBBY2(U)	;OUTPUTTING. CONSIDER ECHO.
	TLNE	T1,L2LHD3	;DURING IGNORE TIME?
	POPJ	P,0		;YES. IGNORE.
	MOVSI	T1,L2LHD2	;FLAG FOR RCV INT
	LDB	T2,LDPECK	;NO. GET CHAR LAST SENT OUT
	CAIE	T2,0(T3)	;IS IT CORRECT?
	TLO	T1,L2LHD5	;NO. PUT ERROR FLAG IN TOO
	IORB	T1,LDBBY2(U)	;SET RCV DONE AND ERROR IF ERROR OCCURRED
IFE FT630H,<
	TLNN	T1,L2LHD1	;HAS XMT FLAG HAPPENED TOO?
	POPJ	P,0		;NO. WAIT FOR IT.
>
RHDERQ:	TLNN	T1,L2LHD5	;ERROR ON RCV INT?
	JRST	XMTHCH		;NO, PROCESS AS TRANSMIT DONE
				;YES. FALL INTO ERROR ROUTINE
RHDERR:	MOVSI	T1,L2LHD4	;IS THIS AN ERROR OR THE RESPONSE TO IT?
	TDNN	T1,LDBBY2(U)	; ..
	JRST	RHDER1		;ERROR.
	ANDCAM	T1,LDBBY2(U)	;RESPONSE. CLEAR RESP FLAG
	MOVE	T2,T3		;CONSIDER WITHOUT PARITY
	ANDI	T2,177		; ..
	CAIN	T2,"O"-100	;CONTROL O?
	JRST	RHDER2		;YES.
	CAIE	T2,"C"-100	;CONTROL C?
	JRST	XMTHCH		;NO, TREAT AS TRANSMIT DONE
	MOVSI	T1,L2LCCS	;YES. MAKE IT LOOK LIKE TWO OF THEM
	IORM	T1,LDBBY2(U)	; ..
RHDER2:	MOVSI	T1,LDLIDL
	IORM	T1,LDBDCH(U)
	MOVSI	T1,LPLIRM
	ANDCAM	T1,LDBPAG(U)
	JRST	RECIN1		;AND GO PROCESS AS RECEIVE INTERRUPT

RHDER1:	MOVSI	T1,L2LHD3+L2LHD4	;ERROR. FLAG FOR IGNORE RCV INTS
	IORM	T1,LDBBY2(U)	; ..
	AOS	T1,ECHCNT	;UPDATE COUNTER
	CAILE	T1,10		;TOO MANY CLOCK REQUESTS?
	JRST	ECHOUT		;YES
	MOVE	T1,TICSEC##	;DELAY FOR HALF SECOND
	LSH	T1,-1
	HRLI	T1,ECHO		;COME TO ECHO AFTER DELAY
	SYSPIF			;PUT REQUEST IN CLOCK QUEUE
	IDPB	T1,CLOCK##	; ..
	IDPB	U,CLOCK##
	SETOM	CLKNEW##
	JRST	ONPOPJ##	;ENABLE INTERRUPTS AND RETURN

ECHOUT:	SOS	ECHCNT		;SO COUNT STAYS RIGHT
	JRST	ONPOPJ##	;ONE LESS QUEUE ENTRY
ECHO:	MOVSI	J,MTTYLN##	;HERE AT CLK LEVEL. CLEAR TERMINAL IGNORE FLAGS
	MOVSI	T1,L2LHD3	;IN ALL TTY LDB'S
	SOS	ECHCNT		;ONE LESS QUEUE ENTRY
ECHOL:	HRRZ	U,LINTAB##(J)	;GET AN LDB ADDRESS
	ANDCAM	T1,LDBBY2(U)	;CLEAR IGNORE BIT
	AOBJN	J,ECHOL		;DO FOR ALL LINES
	POPJ	P,0		;RETURN TO CLOCK LEVEL
>
IFN FTCIMP,<			;(110)
;(270);(110) HERE ON RECEIVE INTERRUPT WHEN QUOTE/ESCAPE ENABLED.
;(270);(110) 	T1 CONTAINS CONTENTS OF LDBQUO(U)
;(270);(110) 	IF CROSSPATCHED TO IMP, PARITY HAS ALREADY BEEN STRIPPED OFF T3
;(270) (can never be here if not crosspatched)
;(270) here to check for some sort of network function character.
;(270) called from RECINT and from PTYPUT.
;(270) returns:
;(270)	  +1	<we know the character and have dealt with it>
;(270)	  +2	<we don't know this character.  continue processing>
;(270) call with character in T3.  clobbers T1,T2 and T4.  T3 set as
;(270)		this routine thinks it should be.
RECQUO:	skipn	t1,ldbquo(u)	;(270) any quotes or anything enabled?
	  pjrst	cpopj1##	;(270) no.  we don't know this characrter, then
	JUMPL	T1,QUOIMI	;(110) JUMP IF QUOTE WAS PREVIOUS CHAR
	TLZE	T1,LQLNET	;(110) DID NETWORK ESCAPE PRECEDE?
	JRST	NETQUO		;(110) YES - TRANSLATE TO TELNET CODE
	HRLM	T3,(P)		;(110) SAVE CHARACTER
	ANDI	T3,177		;(110) MASK TO 7 BITS
	LDB	T2,LDPQUO	;(110) IS IT THE QUOTE CHAR?
	CAIN	T2,(T3)		;(110) ....
	JUMPN	T2,QUOSET	;(110) YES (IF ONE IS DEFINED)
;(270) can't get there from here.
;(270)	JUMPE	F,LTRCHK	;(110) JUMP IF NOT CROSSPATCHED IMP
	LDB	T2,LDPLCL	;(110) IS IT THE LOCAL ESCAPE CHARACTER?
	CAIN	T2,(T3)		;(110) (LET'S PLAY 20 QUESTIONS)
	PJUMPN	T2,TTIDET##	;(110) YES - BREAK THE CROSSPATCH
	LDB	T2,LDPNET	;(110) NO - HOW ABOUT NETWORK ESCAPE?
	CAIN	T2,(T3)		;(110) ...
	JUMPN	T2,NETSET	;(110) YES - IF ONE IS DEFINED
;(110) HERE IF NOT A SPECIAL CHARACTER
LTRCHK:	LDB	T2,LDPSFT	;(110) GET SHIFT CHAR
	CAIN	T2,(T3)		;(110) IS THAT WHAT WAS TYPED?
	JUMPN	T2,SFTSET	;(110) YES (IF SHIFT CHAR DEFINED)
	HLRZ	T3,(P)		;(110) NO - GET BACK SAVED CHAR
	JUMPE	T2,RECQU2	;(110) EXIT IF NO SHIFT CHAR DEFINED
	MOVEI	T2,(T3)		;(110) SHIFTING IN EFFECT - COPY CHARACTER
	ANDI	T2,137		;(110) CLEAR U/L CASE BIT
	CAIL	T2,"A"		;(110) IS IT A LETTER?
	CAILE	T2,"Z"		;(110) ....
	JRST	RECQU2		;(110) NO - DON'T SHIFT
	LDB	T1,LDPSMD	;(110) GET CURRENT SHIFT MODE INDEX
	XCT	SFTTAB(T1)	;(110) SHIFT LETTER APPROPRIATELY
	 XORI	T3,200		;(110) NON-SHIFT MEANS PARITY INVERTED
;(270) still can't get there from here.
;(270)	SKIPE	F		;(110) CROSSPATCHED IMP?
	ANDI	T3,177		;(110) YES - DISCARD PARITY
RECQU2:	MOVSI	T1,LQLSFT	;(110) CLEAR SHIFT BIT
	ANDCAM	T1,LDBQUO(U)	;(110) ....
;(270)	JRST	RECQRT		;(110) RESUME NORMAL PROCESSING
	pjrst	cpopj1##	;(270) not a character we care about.

;(110) CASE TRANSLATION TABLE. DOES NOT SKIP IF CHANGING PARITY

SFTTAB:	TRON	T3,40		;(110) UPSHIFT MODE, NO SHIFT CHAR - TO LC
	TRZE	T3,40		;(110) DOWNSHIFT, NO SHIFT CHAR - TO UC
	TRZE	T3,40		;(110) UPSHIFT, SHIFT CHAR SEEN - TO UC
	TRON	T3,40		;(110) DOWNSHIFT, SHIFT CHAR SEEN - TO LC
;(110) STILL IN FTCIMP
;(110) HERE WHEN PREVIOUS CHAR WAS NETWORK ESCAPE

NETQUO:	ANDI	T3,177		;(110) DISCARD PARITY
	CAIG	T3,"Z"+40	;(110) LOWER CASE RANGE?
	CAIGE	T3,"A"+40	;(110) ....
	 CAIA			;(110)
	TRZ	T3,40		;(110) WAS LOWER CASE LETTER, MAKE INTO UPPER
	MOVE	T4,TELTAB##	;(110) GET AOBJN WORD TO TELNET CONVERSION TABLE
NETQ01:	MOVE	T2,(T4)		;(110) GET AN ENTRY
	CAIE	T3,(T2)		;(110) MATCH?
	 AOBJN	T4,NETQ01	;(110) OLD COLLEGE TRY...
	JUMPG	T4,LQLSTO	;(110) NO MATCH IF POSITIVE
	MOVEM	T1,LDBQUO(U)	;(110) SAVE WHILE WE CAN - THIS TURNS OFF THE
				;(110) NETWORK-ESCAPE-PRECEDE FLAG (LQLNET)
				;(110) BY PRIOR TLZE AT RECQUO+1
	HLLM	T2,(P)		;(110) SAVE TELNET CODE
	MOVEI	T3,.TNIAC##	;(110) PRECEDE WITH TELNET FLAG
	IORI	T3,400		;(110) SEND THRU AS IMAGE CHAR
	PUSHJ	P,RECNXI	;(110) TRY TO SEND IT
;(271)	 CAIA			;(110) SUCCESS
;(271)	PJRST	CPOPJ1##	;(110) NO ROOM - SAY SO WITH SKIP EXIT
	HLRZ	T3,(P)		;(110) GET TELNET CONTROL BACK
	CAIN	T3,.TNAO##	;(110) IF IT IS ABORT OUTPUT FUNCTION,
	 JRST	NETCNO		;(161) CALL TSETBO FIRST
	IORI	T3,400		;(110) MARK AS IMAGE CHAR
	PJRST	RECNXI		;(110) SEND TELNET CONTROL AND RETURN

NETCNO:	PUSH	P,T3		;(161) SAVE THE .TNAO
	PUSHJ	P,TSETBO	;(161) DO OUR PART HERE
	POP	P,T3		;(161)
	IORI	T3,400		;(110) MARK AS IMAGE
	PJRST	RECNXI		;(161) AND SEND THE TELNET COMMAND

;(110) HERE WHEN PREVIOUS CHARACTER WAS QUOTE. PASS LITERALLY

QUOIMI:	TLZ	T1,LQLQUO+LQLNET+LQLSFT ;(110) CLEAR SHIFT/QUOTE BITS
	MOVEM	T1,LDBQUO(U)	;(110) AND STORE IN LDB
	IORI	T3,400		;(110) MARK AS IMAGE CHAR
	PJRST	RECNXI		;(110) PERFORM IMAGE PROCESSING

NETSET:	TLOA	T1,LQLNET	;(110) HERE WHEN NETWORK ESCAPE TYPED
QUOSET:	TLO	T1,LQLQUO	;(110) HERE WHEN QUOTE TYPED
	JRST	LQLSTO		;(110) STORE BITS, DISCARD CHARACTER

;(110) UP SHIFT CREEK IN A LEAKY CHAR WITHOUT A BIT

SFTSET:	TLCE	T1,LQLSFT	;(110) COMPLEMENT SHIFT BIT. IF ALREADY SET,
	TLC	T1,LQLDWN	;(110) ...THEN REVERSE THE TRANSLATION MODE
LQLSTO:	MOVEM	T1,LDBQUO(U)	;(110) STORE THE REVISED STANDARD VERSION
	POPJ	P,		;(110) EXIT FROM RECINT - DISCARD CHARACTER
> ;(110) END IFN FTCIMP
;HERE ON RECEIVE INTERRUPT OF A CONTROL	-C CHARACTER

IFN FTMIC,<			;IF MIC
RICA:	SKIPN	LDBMIC(U)	;IS MIC RUNNING FOR US?
	JRST	RECINA		;NO NORMAL CONTROL CHAR
				;YES - FALL INTO RICC

RICC:	PUSH	P,T1		;SAVE CHARACTER BITS
	SKIPE	T1,LDBMIC(U)	;IS MIC RUNNING FOR US?
	PUSHJ	P,MICRIC	;YES - EXTRA GOODIES
> ;END OF IF MIC
IFE FTMIC,<			;IF NOT MIC
RICC:	PUSH	P,T1		;SAVE CHARACTER BITS
> ;END OF IF NOT MIC
	PUSH	P,T3		;RIDLN CLOBBERS T3
	PUSHJ	P,RIDLN		;DO THE CONTROL-U FUNCTION
	POP	P,T3		;RECOVER ↑C FOR ECHO
	HRRZ	F,LDBDDB(U)
	JUMPE	F,RICC2
	LDB	J,PJOBN##
	LDB	T1,LDPDEB	;DEFERRED ECHO BITS
	DPB	T1,JBYDEB##	;SAVE IN JOB TABLE
RICC2:	MOVSI	T1,L2LCCS	;SEE IF SECOND CONTROL C
	TDNN	T1,LDBBY2(U)	; ..
	JRST	RICC1		;NO
IFN FTTPAG,<
	MOVSI	T1,LDLSTP+LDLSSO;YES - CLEAR STOP BIT
	ANDCAM	T1,LDBDCH(U)
>
	PUSHJ	P,CNCCHK	;YES. AM I ALLOWED TO BELIEVE THE CONTROL-C?
	  JRST RICC1		;SLAVE, OR NOT SECOND. JUST STORE
	PUSHJ	P,TTHALT	;JACCT AND TWO ↑C↑C
	HRRZ	F,LDBDDB(U)	;GET ATTACHED JOB
	JUMPE	F,RICC3		;MAKE SURE THERE IS ONE
	MOVE	T1,DEVMOD(F)	;IS OWNING JOB ATTACHED TO TERMINAL,
	TLNE	T1,TTYATC	;OR JUST USING TERMINAL AS IO DEVICE?
	JRST	RICC3		;ATTACHED. OK TO DO CONTROL C
	MOVEI	S,IODERR	;NOT ATTACHED
	IORB	S,DEVIOS(F)	;GIVE JOB AN ERROR BIT
	PUSHJ	P,TTWAKE	;AND WAKE IT UP
	SETZM	DEVNAM(F)	;MAKE IT INVISIBLE TO DEVSRC
	PUSH	P,U		;SAVE U IN CASE DDB IS KILLED
	PUSHJ	P,PTYDET	;GET LINE FREE OF DDB
	POP	P,U		;RESTORE U
RICC3:	POP	P,T1		;RESTORE STACK LEVEL
	PUSHJ	P,TSETBI	;FORCE ACTION. CLEAR BUFFERS
	PUSHJ	P,TSETBO	;BOTH INPUT AND OUTPUT. COMCON HAS
				; BEEN FLAGGED BY CNCCHK
	MOVE	T2,FILXCP	;POINTER TO CONTROL C ECHO
	JRST	RIFRET		;STORE IT AND RETURN

RICC1:	MOVSI	T1,L2LCCS	;SET "↑C LAST IN" BIT
	IORM	T1,LDBBY2(U)	;NOT SECOND. STORE BIT.
	JRST	RICQ2		;AND TREAT AS RCV CHARACTER
;HERE ON RECEIPT OF A ↑D CHARACTER

	$LOW
RICD:	MOVEI	T2,LDRDSR	;DATASET OR REMOTE
	TDNE	T2,LDBDCH(U)	; ..
	JRST	RECINA		;YES--SAY ↑D
	HLRZ	T2,CD		;GET INSTRUCTION
	CAIE	T2,(JSR)	;BREAK POINT
	JRST	RECINA		;NO--IGNORE
	MOVEM	17,CDSAV+17	;SAVE 17
	MOVEI	17,CDSAV	;PLACE TO SAVE ACS
	BLT	17,CDSAV+16	;SAVE THEM
				;PLACE BREAKPOINT HERE . . .
CD::	MOVSI	17,CDSAV	;RESTORE ALL ACS
	BLT	17,17		;AND
	POPJ	P,		;RETURN FROM INTERRUPT
CDSAV:	BLOCK	20		;PLACE TO SAVE ACS AT CD BREAKPOINT
	$HIGH
;HERE ON CONTROL H (BACKSPACE) TO DETERMINE HOW TO TREAT
;IN THE VARIOUS CASES LIKE APL ETC.

RIBSP:	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSHJ	P,STOPCM
	HLLZ	P1,T1		;SAVE CHARACTER BITS
	LDB	T2,LDPAPL	;GET APL BIT
	JUMPN	T2,RECINA	;JUST STORE IN BUFFER (THIS APL)
IFN FTCAFE&FT2741,<
	MOVEI	T1,LDR2741	;IF 2741...
	TDNE	T1,LDBDCH(U)	;NON APL
	MOVEI	T3,377		;ACT LIKE RUBOUT
>;END OF FTCAFE&FT2741
	JRST	RIDELB
;HERE ON RECEIPT OF A CARRIAGE RETURN (CONTROL M)

RICM:	MOVEI	T2,L2RXON	;IS XON TRUE?
	TDNE	T2,LDBBY2(U)	;...
	JRST	RECINA		;YES. NOTHING SPECIAL. STORE.
	PUSHJ	P,RECINA	;NO. FIRST STORE THE C-R
IFN FTCIMP,<			;(110)
	CAIA			;(110) NON-SKIP MEANS WAS SENT
	JRST	CPOPJ1##	;(110) SKIP MEANS COULDN'T BUFFER IT
>;(110)
	MOVEI	T3,12		;THEN GET A L-F (EVEN PARITY)
	JRST	RECIN1		;AND GO PRETEND IT WAS TYPED IN.

;HERE ON RECEIVE INTERRUPT OF A CONTROL O

RICO:	MOVEI	T1,LDROSU	;COMPLEMENT STATE OF OUTPUT SUPPRESS BIT
	XORM	T1,LDBDCH(U)	;IN LINE DATA BLOCK
	DPB	T1,LDPSVC	;CLEAR ANY SAVED CHARACTER
IFN LDROSU&777,<PRINTX ?LDROSU AND LDPSVC CONFLICT>
	PUSHJ	P,TSETBO	;CLEAR OUTPUT BUFFER
	MOVE	T2,FILXOP	;POINTER TO ↑O ECHO
	JRST	RIFRET		;STORE AND RETURN

;HERE TO DISCARD INPUT CHARACTER SUCH AS NULL OR "USED" ↑O

	RINUL==CPOPJ##		;RETURN FROM RECINT.
;HERE ON RECEIVE INTERRUPT OF A CONTROL Q (XON)

RICQ:	PUSH	P,T1		;SAVE CHARACTER BITS
	MOVSI	T1,L2LTAP	;HAS TERMINAL TAPE COMMAND BEEN TYPED?
	TDNN	T1,LDBBY2(U)	; ..
	JRST	RICQ2A		;NO. DON'T DO ANYTHING SPECIAL
	MOVEI	T1,L2RXON	;TURN ON BIT IN LINE CHAR WORD
	IORM	T1,LDBBY2(U)	; ENTER HERE FOR OTHER BITS TOO
	MOVEI	T1,ISRCHP
	PUSHJ	P,@LDBISR(U)	;TELL REMOTE STATION ABOUT THE ↑Q.
	POP	P,T1
	JRST	CHKXN1
RICQ2A:
IFN FTTPAG,<
	MOVSI	T1,LDLSTP+LDLSSO;CLEAR STOP BIT FOR TERMINAL OUTPUT
	ANDCAM	T1,LDBDCH(U)	;..
	MOVSI	T1,LPLPAG	;HAS "SET TERMINAL PAGE" BEEN ENABLED
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) ALWAYS SEND IF CROSSPATCHED
>				;(110) END IFN FTCIMP
	TDNN	T1,LDBPAG(U)	;..
	JRST	RICQ2		;NO, DON'T DO ANYTHING SPECIAL WITH ↑Q
IFN FTTVP,<PUSHJ P,CLRPCT>	;CLEAR PAGE COUNTER
	MOVEI	T1,ISRCHP	;TELL REMOTE STATION ABOUT ↑Q
	PUSHJ	P,@LDBISR(U)
	POP	P,T1		;RESTORE T1
	PJRST	TOPOKE		;AND GO START OUTPUT AGAIN
> ;IFN FTTPAG

RICQ2:	POP	P,T1		;RESTORE CHARACTER BITS
	JRST	RECINA		;AND ACCEPT THE CHARACTER
IFN FTMIC,<			;IF MIC

;HERE ON RECEIVE INTERRUPT OF CONTROL P (PROCEED)

RICP:	SKIPN	T2,LDBMIC(U)	;IS MIC RUNNING FOR US?
	JRST	RECINA		;NO - JUST RETURN
	TLO	T2,LDLCHK!LDLMCP;YES - SET UP ↑P FLAG
RICB2:	MOVEM	T2,LDBMIC(U)	;PUT WORD BACK
RICB3:	PJRST	MICWAK		;WAKE UP MIC

;HERE ON RECEIVE INTERRUPT OF CONTROL B (BREAK)

RICB:	SKIPN	T2,LDBMIC(U)	;IS MIC RUNNING FOR US?
	JRST	RECINA		;NO TREAT AS ORDINARY CHAR
	TLO	T2,LDLCHK!LDLMCB;YES - SET UP ↑B FLAG
	JRST	RICB2		;AND TREAT AS ↑P
> ;END OF IF MIC
;HERE ON A CONTROL T
IFN FTWATCH,<
RICT:	PUSHJ	P,DOCTLT	;PROCESS THE CONTROL-T
	  JRST	RECINA		;WE WANT TO STORE IT
	  JRST	[PUSHJ P,CLRPCT
		 JRST TTFORC]	;WE WANT TO DO USESTAT
	JRST	RIBUSY		;LINE ALREADY HAS A COMMAND

DOCTLT:
IFN FTCIMP,<			;(110)
	SKIPN	T2,LDBIMP(U)	;(110) ALWAYS STORE IF CROSSPATCHED TO IMP
>;(110)
	LDB	T2,LDPRTC	;GET BIT FOR TERMINAL RTCOMPAT
	JUMPN	T2,CPOPJ##	;IF IT IS =1 GIVE NON-SKIP RETURN
	HLL	U,LDBDCH(U)	;GET DEVICE FLAGS
	TLNE	U,LDLSLV	;SLAVE?
	JRST	CPOPJ##		;YES--DO NOT FORCE CONTROL-T
	HRRZ	F,LDBDDB(U)	;GET LINKED DDB ADDRESS
	JUMPE	F,RICT1		;FORCE COMMAND IF ZERO
	MOVE	T2,DEVMOD(F)	;GET DEVICE BITS
	TLNN	T2,TTYATC	;CONTROLLING TERMINAL?
	JRST	CPOPJ##		;NO--JUST STORE THE CONTROL-T
RICT1:	MOVEI	T1,TTFCXW	;FORCE USESTAT
	SKIPL	(U)		;COMMAND ALREADY PENDING?
	JRST	CPOPJ1##	;NO--GIVE SINGLE SKIP
	JRST	CPOPJ2##	;YES--GIVE DOUBLE SKIP
> ;END FTWATCH
;HERE ON A CONTROL R

RICR:
IFN FTCIMP,<			;(110)
	SKIPN	T2,LDBIMP(U)	;(110) ALWAYS STORE IF CROSSPATCHED TO IMP
>;(110)
	LDB	T2,LDPRTC	;RTCOMPATABILITY IN EFFECT?
	JUMPN	T2,RECINA	;JUMP IF SO, STORE CHARACTER IN THE INPUT BUFFER
	PUSHJ	P,FULLCQ	;COMMAND OR FULL CHARACTER SET?
	  JRST	RECINA		;YES, STORE CHARACTER
	SETZ	T3,		;ASSUME NOT A VIDEO TERMINAL
	PUSHJ	P,TTVID		;IS IT?
	  JRST	RICR2		;NO, NOTHING FANCY TO DO
	HLRZ	T3,TCRTAB+1(T1)	;ADDRESS OF EOL TABLE
	JUMPE	T3,RICR2	;VIDEO TERMINAL BUT CAN'T DO EOL
	MOVSI	T3,LDLUAR	;DOING CONTROL R
	PUSHJ	P,HPOS		;CURRENT HORIZONTAL POSITION
	LDB	T4,PRPOS	;LENGTH OF THE PROMPT
	CAMN	T2,T4		;CURSOR AT THE END OF THE PROMPT?
	JRST	RICR1		;YES, NOTHING TO SKIP OVER
	LDB	T2,LDPFCT	;FILLER REPEAT COUNT
	JUMPN	T2,RICR1	;IF NON-ZERO, THE PROMPT HAS BEEN SPACED OVER
	IORM	T3,LDBTTW(U)	;PROMPT HASN'T BEEN SPACED OVER SO INDICATE ↑R PROCESSING
	JRST	RICU2		;AND USE ↑U CODE TO SKIP THE PROMPT
RICR1:	ANDCAM	T3,LDBTTW(U)	;DONE WITH ↑R PROMPT PROCESSING
	DPB	T3,LDPSVC	;NO LEFT OVER CHARACTER
	DPB	T3,LDPFCT	;AND NO FILLER COUNT
	MOVEI	T2,0		;FILL POINTER
	PUSHJ	P,SETFLP	;ZAP
RICR2:	MOVEI	T1,TTFCXT	;RETYPE THE LINE
	SKIPGE	(U)		;IS THERE ALREADY AN OUTSTANDING COMMAND?
	JRST	RIBUSY		;YES, SAY BUSY
	PUSHJ	P,TTFORC	;FORCE THE RETYPE COMMAND
	JUMPN	T3,CPOPJ##	;ALL DONE IF NOT A HARDCOPY TERMINAL
	MOVE	T2,FLLBSC	;HARDCOPY,
	PJRST	RIFRET		; RETYPE ON A NEW LINE
;HERE ON RECEIVE INTERRUPT OF CONTROL S (XOFF)

RICS:	PUSH	P,T1		;SAVE CHARACTER BITS
	MOVEI	T1,L2RXON	;CLEAR THIS BIT
	ANDCAM	T1,LDBBY2(U)	;IN LINE CHARACTERISTICS WORD
	MOVSI	T1,LDLSTP	;GET THE "STOPPED BY ↑S BIT"

IFN FTTPAG,<
	PUSHJ	P,STPOIP
	  JRST	RICQ2
	JRST	TPOPJ##
>
IFE FTTPAG,<JRST RICQ2>

IFN FTTPAG,<
STPOIP:	MOVSI	T2,LPLPAG	;HAS "SET TERMINAL PAGE" BEEN ENABLED?
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) ALWAYS STORE IF CROSSPATCHED TO IMP
>;(110)
	TDNN	T2,LDBPAG(U)	;...
	POPJ	P,		;NO, DON'T DO ANYTHING SPECIAL
	IORM	T1,LDBDCH(U)	;NO MORE OUTPUT UNTIL XON IS TYPED
IFN FTTVP,<
	PUSHJ	P,CLRPCT
>
	PUSHJ	P,SETCHP	;TELL FE'S TO STOP NOW
	JRST	CPOPJ1##
> ;IFN FTTPAG

BEATIT:	SKIPA	T2,[POINT 9,GAWTXT-1,26]
RIBUSY:	MOVE	T2,[POINT 9,BSYTXT]
	JRST	RIFRET

BSYTXT:	BYTE	(9)134,102,165,163,171,FLLFLG
GAWTXT:	BYTE	(9)123,164,341,356,344,240,341,154,157,356,145,FLLFLG

IFN FTTVP,<
;ROUTINES TO IMPLEMENT 'TERMINAL PAGE N'

CLRPCT::SETZ	T2,
	DPB	T2,LDPPCT	;CLEAR COUNTER
	POPJ	P,

INCPCT:	LDB	T2,LDPPCT
	ADDI	T2,1
	DPB	T2,LDPPCT
;;	PJRST	CHKPCT

CHKPCT:
IFN FTCIMP,<			;(110) DISABLE AUTO STOP FOR IMPS
	SKIPE	LDBIMP(U)	;(110) cross patched out?
	  pjrst	ClrPct		;(110) yes.  clear count, don't stop
>;(110)
IFN FTNET,<
	MOVE	T1,LDBREM(U)	;GET THE REMOTE BITS,
	TLNN	T1,LRLVTM	;  AND IF THIS IS A VTM LINE
>
	PUSHJ	P,PTBTCH##	;CHECK FOR BATCH PTY
	  POPJ	P,		;DISABLE AUTO STOP FOR BATCH OR VTM LINES
	LDB	T1,LDPPSZ	;PAGE SIZE
	JUMPE	T1,CPOPJ##	;IF NO AUTO PAGE SELECTED
	CAIGE	T2,-1(T1)	;COMPARE COUNT WITH SIZE, ALLOW FOR LAST LF
	POPJ	P,
	MOVSI	T1,LDLSSO	;GET "SCNSER STOPPED OUTPUT" BIT
	PUSHJ	P,STPOIP	;IF AT LIMIT, STOP OUTPUT, CLEAR COUNT
	  POPJ	P,		;STPOIP NON-SKIPS IF TERMINAL NO PAGE
	MOVE	T2,[POINT 9,[BYTE (9)207]] ;A LONE BELL
	PJRST	SETFLP		;REMIND THE USER OF TTY PAGE N
>
;PACKED IMAGE MODE (PIM) RECEIVE CHARACTER PROCESSING

REPIM:
IFN FTTPAG,<
	MOVSI	T2,LPLPAG
	TDNN	T2,LDBPAG(U)	;HAS SET TERMINAL PAGE BEEN DONE?
	JRST	REPIM3		;NO, DON'T LOOK FOR XON/XOFF
	CAIE	T3,221		;THIS CHARACTER AN XON?
	CAIN	T3,21		;IN EITHER PARITY?
	JRST	RICQ		;YES, TREAT AS NON PIM XON
	CAIE	T3,223		;OR IS IT AN XOFF
	CAIN	T3,23		;
	JRST	RICS		;TREAT AS NON PIM XOFF IF SO
>;END OF FTTPAG
REPIM3:	MOVE	T2,LDBTIC(U)	;# OF CHARS INPUT
	CAMG	T2,RPIMWN	;TIME TO WARN HIM?
	JRST	REPIM2		;NO, NOT YET
	SUBI	T2,↑D20		;IS HE OVER 20 CHARS?
	CAMLE	T2,RPIMWN	;OVER CURRENT LIMIT?
	JRST	[MOVE	T1,LDBPAG(U)
		 TLNN	T1,LPLXOF	;SENT XOF YET?
		 JRST	RPIM25		;NO, DO IT NOW
		 JRST	RCHLT1]		;YES, EAT CHAR
RPIM25:	PUSHJ	P,SNDXOF	;SEND XOFF
	PUSHJ	P,RCVWAK
REPIM2:	SKIPG	TTFREN##	;ROOM IN CHUNK SPACE?
	JRST	RCHLT2		;NO, SHUT IT DOWN
	TRO	T3,400		;MARK NINTH BIT
	SCNOFF			;NO INTERRUPTS
	STCHK	T3,LDBTIP(U)	;PLACE CHARACTER IN BUFFER
	AOS	LDBTIC(U)	;INCREMENT COUNT
	SETZM	LDBECC(U)
	MOVE	T2,LDBTIP(U)
	MOVEM	T2,LDBECT(U)	;MAKE CHAR LOOK ECHOED
	SCNON			;ALLOW INTERRUPTS
	SKIPN	T2,LDBPBK(U)	;GET AND TEST BREAK CHARACTER WORD
	JRST	RCVWAK		;NOTHING SPECIFIED, BREAK ON ALL
	ANDI	T3,377		;CLEAR NINTH BIT FOR TEST
REPIM1:	LSHC	T1,9		;GET TEST CHARACTER
	XOR	T1,T3		;XOR WITH RECEIVED CHAR
	TRNN	T1,377		;MATCH?
	JRST	RCVWAK		;YES, BREAK CHAR, WAKE AND DISMISS
	JUMPE	T2,CPOPJ##	;DONE, DISMISS INTERRUPT
	JRST	REPIM1		;NO, TRY NEXT
SNDXOF::MOVSI	T1,LPLXOF	;GET THE "XOFF HAS BEEN SENT" BIT
	TDNE	T1,LDBPAG(U)	;HAVE WE SENT ONE?
	POPJ	P,		;IF SO, DON'T SEND TWO
	IORM	T1,LDBPAG(U)	;SET THE BIT SO WE DON'T SEND ANOTHER
	PUSH	P,T3		;ISR WILL CLOBBER THIS
	MOVEI	T3,1		;CODE TO SAY BUFFER LOW
	MOVEI	T1,ISRREM	;
	PUSHJ	P,@LDBISR(U)	;NOW CALL ISR
	  SKIPA	T2,FLPPXF	;ISR DID'T SEND IT. WE MUST
	JRST	T3POPJ		;XOFF SENT, POP T3 AND RETURN
	PUSHJ	P,SETXNP	;SET FILLER
	PUSHJ	P,TOPOKE	;MAKE SURE IT GETS OUT
	POP	P,T3		;RESTORE T3
	POPJ	P,		;RETURN

;HERE ON A CONTROL U AT INTERRUPT LEVEL ONLY

RICU:	PUSHJ	P,FULLCQ	;BREAK ON ALL CHARACTERS?
	  JRST RECINA		;YES. STORE THE ↑U IN BUFFER
	LDB	T1,LDPFCT	;FILLER REPEAT COUNT
	JUMPN	T1,RICU1	;JUMP IF NOT THE FIRST TIME
	PUSHJ	P,RIDLN		;BACKUP THE INPUT BUFFER TO THE LAST BREAK CHARACTER
	SKIPL	LDBDCH(U)	;LINE IDLE?
	JRST	RINUL		;NO, GO AWAY
	MOVE	T2,FILXUP	;ASSUME HARDCOPY \↑U<CRLF>
RICU1:	PUSHJ	P,TTVID		;VIDEO TERMINAL?
	  JRST	RIFRET		;NO, ECHO TRADITIONAL STUFF
RICU2:	PUSHJ	P,HPOS		;HORIZONTIAL POSITION
	LDB	T3,PRPOS	;LENGTH OF THE PROMPT
	CAMN	T2,T3		;AT THE END OF THE PROMPT?
	JUMPN	T3,RINUL	;YES, NOTHING TO DO
	HLRZ	T2,TCRTAB+1(T1)	;ADDRESS OF THE ERASE TABLE
	JUMPE	T2,[MOVE T2,FILXUP ;VIDEO TERMINAL BUT CAN NOT DO EOL
		    JRST RIFRET]
	JUMPE	T3,[MOVEI T1,1	;IF NO PROMPT, I.E. AT LEFT MARGIN,
		    AOJA T2,RICU4] ;CARRIAGE RETURN, ERASE END OF LINE
	LDB	T1,LDPFCT	;FILLER REPEAT COUNT
	JUMPN	T1,RICU3	;JUMP IF SPACING OVER THE PROMPT
	DPB	T3,LDPFCT	;REMEMBER NUMBER OF CHARACTERS TO SPACE OVER
	MOVE	T2,(T2)		;CARRIAGE RETURN
	MOVEI	T1,25		;DOING CONTROL U
	DPB	T1,LDPSVC	;REMEMBER THAT TO GET BACK HERE
	JRST	RIFRT1		;SET HPOS TO BEGINNING OF LINE AND TYPE CARRIAGE RETURN
RICU3:	CAIE	T1,1		;AT LAST CHARACTER OF THE PROMPT?
	SKIPA	T2,1(T2)	;NO, CURSOR RIGHT
RICU4:	MOVE	T2,2(T2)	;YES, CURSOR RIGHT, ERASE END OF LINE
	MOVSI	T4,LDLUAR	;CONTROL R BIT
	TDNE	T4,LDBTTW(U)	;PROCESSING CONTROL R?
	CAIE	T1,1		;YES, LAST CHARACTER OF THE PROMPT BEEN SPACED OVER?
	SOSA	T1		;NO, DECREMENT LENGTH OF THE PROMPT
	SKIPA	T4,[22]		;CONTROL R PROCESSING
	MOVEI	T4,25		;CONTROL U OR MORE CONTROL R
	DPB	T1,LDPFCT	;UPDATED FILLER REPEAT COUNTER
	DPB	T4,LDPSVC	;POST PROCESSING DISPATCH
	SKIPN	T1		;IF LAST CHARACTER,
	DPB	T1,LDPSVC	;NO POST PROCESSING
	JUMPE	T3,RIFRT1	;DONE IF NO PROMPT
	MOVEI	T3,40		;SPACE
	PUSHJ	P,ADJHP		;ADJUST HORIZONTAL POSITION 1 CHARACTER TO THE RIGHT
	JRST	RIDEL3		;SPACE OVER PROMPT CHARACTER
RIDLN:	PUSHJ	P,STOPCM	;STOP COMCON
	SCNOFF			;NO INTERRUPTS
RIDLN1:	SKIPN	T1,LDBBKU(U)	;ANY BREAK POSITION SAVED?
	PJRST	TSETI2		;NONE THERE. MEANS ONLY THIS LINE IN BFR
	CAME	T1,LDBTIP(U)	;ANYTHING TO DELETE ?
	PUSHJ	P,DELCHR	;DELETE 1 CHAR
	  JRST	SONPPJ		;NOTHING LEFT TO DELETE
	JRST	RIDLN1		;LOOP OVER LINE

DELCHR:	SOSGE	T3,LDBECC(U)	;ANY LEFT TO ECHO?
	JRST	[SETZB	T3,LDBECC(U)	;CLEAR ECHO COUNT
		SOSL	LDBTIC(U)	;CHECK FOR UNECHOED INPUT
		JRST	DELCH3		;GO ERASE THOSE TOO
		SETZM	LDBTIC(U)	;CLEAR INPUT COUNT
		MOVE	T1,LDBTIP(U)
		MOVEM	T1,LDBECT(U)	;ENSURE EMPTY ECHO STREAM
		POPJ	P,]		;RETURN
DELCH3:	MOVE	T1,LDBTIP(U)	;GET INPUT PUTTER
	ADD	T1,[9B5]	;BACK 1 BYTE
	TLNE	T1,400000	;CHECK FOR BIT OVERFLOW
	SUB	T1,[<↑D36>B5+1]	;BACK TO PREVIOUS WORD
	MOVEI	T2,CK.BDY##(T1)	;SEE IF HIT HEADER WORD
	TRNN	T2,CK.BDY##	;WELL...
	JRST	[HLRZ	T1,CK.BTH##(T2)	;BACKUP
		JUMPE	T1,CL0STP	;IF A ZERO POINTER, MUST DIE
		ADD 	T1,[POINT 9,CK.BDY##,35] ;MAKE INTO BYTE POINTER
		JRST	.+1]
	MOVEM	T1,LDBTIP(U)	;STORE ADJUSTED POINTER
	JUMPN	T3,CPOPJ1##	;IF NO ECHO STREAM INTACT
	MOVEM	T1,LDBECT(U)	;NO, MAKE SURE IT STARTS CORRECTLY
	JRST	CPOPJ1##

ZAPIN:	SCNOFF			;OOPS, COUNT WENT NEGATIVE
	SETZM	LDBBKC(U)
	SETZM	LDBTIC(U)
	SETZM	LDBECC(U)	;CLEAN UP INPUT
	MOVE	T2,LDBTIT(U)	; COUNTERS AND
	MOVEM	T2,LDBTIP(U)	; POINTERS,
	MOVEM	T2,LDBECT(U)	; INCLUDING ECHO
	PJRST	SONPPJ
RWARN:
;(271)IFN FTCIMP,<			;(110)
;(271)	MOVEI	T1,LDRIMP	;(110) TOO MUCH INPUT - TRY TO STOP THE USER
;(271)	TDNE	T1,LDBDCH(U)	;(110) IS IT COMING FROM THE IMP?
;(271)	JRST	TPOPJ1##	;(110) YES - STOP THE IMP INPUT
;(271)>;(110)
	CAIGE	T2,↑D300	;IF HE IS WAY OVER, OR
	SKIPG	TTFREN##	;WE ARE OUT OF CHUNKS
	JRST	RECHLT		;THROW AWAY THE INPUT CHARACTER
	PUSHJ	P,PTBTCH##	;CHECK IF OLD PTY OR BATCH
	  JRST	RWARNX		; CAN'T SEND XOFF
	PUSHJ	P,SNDXOF	;SEND XOFF
	JRST	RWARNX		;CONTINUE INPUT ROUTINE

RECHLT:	POP	P,T1		;RESTORE T1
;(271)IFN FTCIMP,<			;(110)
;(271)	MOVEI	T1,LDRIMP	;(110) LOOK FOR ITY
;(271)	TDNE	T1,LDBDCH(U)	;(110) ....
;(271)	JRST	CPOPJ1##	;(110) YES STOP THE IMP INPUT
;(271)>;(110)
RCHLT1::MOVE	T2,FLPBEL	;THIS IS TOO MUCH. TELL HIM
	PUSHJ	P,SETXNP	;SET FILLER FLAG
	MOVEI	T3,2		;CODE FOR CHAR NOT STORED
	MOVEI	T1,ISRREM
	PUSHJ	P,@LDBISR(U)	;TELL THE ISR CHAR NOT STORED
RCHLT2:	PUSHJ	P,TOPOKE	;START TYPING IF NEEDED (USUALLY NOT NEEDED)
	PJRST	ECHBRK		;TRY TO WAKE JOB, THEN
				;DISMISS INTERRUPT, JUNKING CHARACTER

RECVRG:	SCNOFF			;NO INTERRUPTS
	SKIPE	T1,LDBTIT(U)	;IF ANY POINTER
	JRST	RECVR1		;IF POINTER ALREADY EXISTS
	PUSHJ	P,GETCKZ	;GET A FREELIST CHUNK
	ADD	T1,[POINT 9,1,8];MAKE INTO A BYTE POINTER
	MOVEM	T1,LDBTIT(U)	;SET TAKER
RECVR1:	MOVEM	T1,LDBTIP(U)	;SET PUTTER BACK TO TAKER
	MOVEM	T1,LDBECT(U)	;AND THE ECHO POINTER
	SETZM	LDBBKU(U)	;BREAK LOCATION
	JRST	SONPPJ
;HERE ON A RUBOUT OR CONTROL W AT INTERRUPT LEVEL

RIDEL:	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSHJ	P,STOPCM
	HLLZ	P1,T1		;SAVE CHARACTER BITS
RIDELB:	PUSHJ	P,FULLCQ	;BREAK ON ALL CHARS, OR FCS?
	  JRST	RECINA		;YES. STORE THE RUBOUT
	LDB	P2,LDBTIP(U)	;GET CHARACTER TO BE ERASED
	ANDI	P2,177		;ONLY 7 BITS
	TLNE	P1,CHDELW	;CONTROL W?
	JRST	RIDELX		;IGNORE PAPER TAPE BITS
	MOVEI	T2,L2RXON	;PAPER TAPE IN EFFECT?
	TDNE	T2,LDBBY2(U)	;YES, DISCARD RUBOUT
	JRST	RINUL		;YES. DISCARD RUBOUT
RIDELX:	HLR	P1,CHTABL(P2)	;GET BITS FOR CHARACTER BEING DELETED
	MOVSI	T2,LDLNAN	;ALPHA-NUMERIC BIT
	LDB	T1,LDPFCT	;FILLER REPEAT COUNT
	JUMPN	T1,RIDELY	;JUMP IF NOT FIRST TIME
	TLNE	P1,CHDELW	;CONTROL W?
	TRNE	P1,CHPUNC	;SKIP IF NOT A PUNCTUATION CHARACTER
	JRST	RIDEL5		;NO, GO DO DELETE
	MOVEI	T1,1		;NOT REALLY A FILLER COUNT
	DPB	T1,LDPFCT	;BUT IT CAUSES US TO GET HERE AGAIN
	MOVSI	T2,LDLUAW!LDLNAN;INDICATE
	CAIE	P2,11		;A TAB?
	CAIN	P2,40		; OR A SPACE
	TLZ	T2,LDLNAN	;NO, ALPHANUMERIC NOT SEEN YET
	JRST	RIDELW		;GO DELETE THIS CHARACTER
RIDELY:	CAIE	P2,11		;A TAB?
	CAIN	P2,40		;OR A SPACE?
	JRST	[TDNN T2,LDBTTW(U) ;YES, ALREADY ERASED AN ALPHA-NUMERIC?
		JRST RIDEL5	;NO, ERASE IT
		JRST RIDELZ]	;YES, EVERY THING THE USER WANTED ERASED HAS BEEN
	TRNE	P1,CHPUNC	;IS THIS CHARACTER PUNCTUATION?
	JRST	RIDELZ		;YES, ALL DONE ERASING
RIDELW:	IORM	T2,LDBTTW(U)	;NO, REMEMBER THAT AN ALPHA-NUMERIC CHARACTER WAS SEEN
	JRST	RIDEL5		;AND GO DELETE THE CHARACTER
RIDELZ:	MOVSI	T1,LDLUAW!LDLNAN;NO LONGER PROCESSING CONTROL W
	ANDCAM	T1,LDBTTW(U)	;CLEAR ALPHA-NUMERIC REMINDER
	DPB	T1,LDPFCT	;AND FILLER REPEAT COUNT
	POPJ	P,		;THE WORD HAS BEEN ERASED SO GO AWAY
RIDEL5:	PUSHJ	P,TTVID
	  TDZA	P3,P3
	HRRZ	P3,TCRTAB+1(T1)
	SKIPE	LDBECC(U)	;IF BAD DATA NOT YET ECHOED
	TLO	U,LDLNEC	;DON'T ECHO ERASURE
	SCNOFF			;NO INTERRUPTS HERE
	MOVE	T2,LDBTIP(U)	;GET ADDRESS OF INPUT STREAM
	CAMN	T2,LDBBKU(U)
	JRST	RIDEL1
	PUSHJ	P,DELCHR	;DELETE THE LAST INPUT CHARACTER
	  JRST	RIDEL1		;IF INPUT STRING DELETED
	SCNON			;ALLOW INTERRUPTS NOW
RIDEL6:	TLNN	P1,CHDEL	;RUBOUT?
	SETZ	P2,0		;NO--SPECIAL ECHO
IFE FTCIMP,<			;(110)
	TLNN	U,LDLNEC	;UNLESS NO ECHO
>;(110)
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) IF CROSSPATCHED, OR
	TLNE	U,LDLNEC	;(110) ...IF ECHO OFF,
	SKIPA			;(110) DO NOT ECHO
>;(110)
	DPB	P2,LDPSVC	;SAVE FOR AFTER BACKSLASH
	MOVEI	T2,1		;A PHONY BYTE POINTER TO A NULL
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) CROSSPATCHED? DO NOT ECHO BACKSPACE
>;(110)
	TLNE	U,LDLNEC	;ECHO OFF?
	JRST	RIDEL3		;YES. DON'T OUTPUT
IFN FTCAFE&FT2741,<
	MOVEI	T3,LDR2741
	TDNE	T3,LDBDCH(U)
	JRST	RIDEL3
>

;CONTINUED ON NEXT PAGE
;HERE TO ECHO THE RUBOUT
	MOVE	T3,LDBDCH(U)	;IF ALREADY
	TDNN	T3,[LDLLCP,,LDRHLF] ;ECHOED, DON'T BUT DO UPDATE HPOS
	MOVE	T2,[POINT 9,[BYTE (9)210,0]]
	TLNN	P1,CHDEL	;RUBOUT OR BACKSPACE
	JRST	RIDEL4		;BACKSPACE (ECHO AS SELF)
	JUMPE	P3,RIDEL9	;A VIDEO TERMINAL?
	CAIE	P2,11		;A TAB?
	JRST	RIDEL7		;NO, ERASE 1 OR 2 CHARACTERS
	SCNOFF
	SKIPN	P1,LDBBKU(U)	;POSITION OF BREAK CHARACTER IN BUFFER
	MOVE	P1,LDBTIT(U)	;NONE, USE START OF THE BUFFER
	LDB	P2,PRPOS	;INITIALIZE CHARACTER COUNT
RIDELA:	CAMN	P1,LDBTIP(U)	;AT THE END?
	JRST	RIDELD		;YES
	LDCHK	T3,P1		;GET NEXT CHARACTER
	ANDI	T3,177		;JUST SEVEN BITS
	CAIE	T3,11		;A TAB?
	JRST	RIDELC		;NO
	TRZ	P2,7		;CLEAR LOW BITS
	ADDI	P2,10		;NEXT TAB STOP
	JRST	RIDELA		;LOOP OVER ALL CHARACTERS IN THE INPUT BUFFER
RIDELC:	MOVE	T1,CHTABL(T3)	;ECHO BITS
	TLNE	T1,CHUAE	;ECHO AS ↑X?
	ADDI	P2,1		;YES, COUNT IT AS 2 CHARACTERS
	AOJA	P2,RIDELA	;LOOP

;HERE WITH P2 = THE HORIZONTAL POSITION DUE TO TYPE IN

RIDELD:	SCNON
	PUSHJ	P,HPOS		;GET ACTUAL HORIZONTAL POSITION
	SUBI	T2,(P2)		;MINUS NUMBER OF CHARACTERS TYPED IN
	PUSHJ	P,BACKUP	;ADJUST HORIZONTAL POSITION
	JRST	RIDEL8		;ERASE BACK TO TAB STOP
RIDEL7:	MOVE	T1,CHTABL(P2)	;GET BITS TO CHECK FOR SPECIAL ECHOING
	MOVEI	T2,1		;ASSUME A SINGLE CHARACTER WAS ECHOED
	TLNE	T1,CHUAE	;REALLY ↑X ECHO?
	MOVEI	T2,2		;YES, ERASE 2 CHARACTERS
	PUSHJ	P,BACKUP	;ADJUST HORIZONTAL POSITION
RIDEL8:	MOVNI	T2,-10(T2)	;RELATIVE ADDRESS OF BYTE POINTER FOR ERASING
	TRNE	T2,-10		;LINE WRAP AROUND?
	MOVEI	T2,0		;NOT QUITE RIGHT BUT RIGHT IS HARD
	ADD	T2,P3		;ADDRESS OF BYTE POINTER FOR ERASING
	MOVE	T2,(T2)		;BYTE POINTER TO ERASE TABLE
	MOVEI	T1,0		;ZERO LDPSVC
	DPB	T1,LDPSVC	;SO CHARACTER DOESN'T GET ECHOED AGAIN
	JRST	RIDEL3		;GO ERASE THE CORRECT NUMBER OF CHARACTERS
RIDEL9:	MOVEI	T1,0
	MOVE	T3,LDBDCH(U)	;DIFFERENT FORMAT IF LOCAL COPY
	TDNN	T3,[LDLLCP,,LDRHLF]
	MOVSI	T1,L2LDEL	;WAS DELETE LAST CHARACTER TOO?
	TDNN	T1,LDBBY2(U)	;IF SO, DON'T OUTPUT ANOTHER BACKSLASH
	JRST	RIDEL0		;NO. GO SET UP A BACKSLASH
	MOVEI	T2,1		;PHONY BYTE POINTER
	JRST	RIDEL3		;GO STORE AND RETURN

RIDEL0:	IORM	T1,LDBBY2(U)	;STORE THAT THIS IS DELETE
	AOS	LDBHPS(U)	;COUNT BACKSLASH POSITION
	MOVE	T2,FLLBSP	;GET POINTER TO BACKSLASH
	JRST	RIDEL3		;GO STORE AND RETURN

RIDEL4:	MOVEI	T3,10		;UPDATE HPOS BY
	PUSHJ	P,ADJHP		; MINUS ONE
	PJRST	RIDEL3		;GO STORE AND RETURN

;SUBROUTINE TO ADJUST HORIZONTAL POSITION WHEN ERASING CHARACTERS
;CALL WITH T2 = NUMBER OF POSITIONS TO BACKUP, RETURNS CPOPJ, T2 INTACT

BACKUP:	PUSH	P,T2		;SAVE T2
	MOVEI	T3,10		;BACKSPACE
BACKU1:	PUSHJ	P,ADJHP		;BACKUP 1 CHARACTER
	SOJG	T2,BACKU1	;LOOP FOR ALL
	JRST	T2POPJ		;RESTORE T2 AND RETURN

;SUBROUTINE TO DETERMINE IF THE CURRENT TERMINAL IS A VIDEO TERMINAL
; I.E., SPECIFIED AS SUCH BY THE USER TYPING A TTY TYPE COMMAND
; RETURNS CPOPJ IF NOT, CPOPJ1 IF SO, T1 POINTS AT CHARACTERISTICS TABLE
; ENTRY FOR THE TERMINAL TYPE

TTVID:	MOVSI	T1,LDLLCP	;LOCAL COPY BIT
	TDZE	T1,LDBDCH(U)	;LINE DOING OWN ECHOING
	POPJ	P,		;YES, AVOID VIDEO STUFF (T1=0)
	LDB	T1,LDPTTT	;GET TERMINAL TYPE AS SET BY COMMAND
	JUMPE	T1,CPOPJ##	;GO IF NONE SPECIFIED
	TRZE	T1,100		;CUSTOMER DEFINED TERMINAL TYPE ?
	MOVNI	T1,(T1)		;YES, NEGATIVE TABLE INDEX
	LSH	T1,1		;2 WORDS PER ENTRY
	SKIPE	TCRTAB+1(T1)	;SKIP IF NOT A VIDEO TERMINAL
	AOS	(P)		;IT IS!
	POPJ	P,		;RETURN
RIDEL1:	SCNON
	JUMPN	P3,RIDELZ
	SKIPL	LDBDCH(U)	;IS OUTPUT IN PROGRESS?
	JRST	RIDELZ		;YES.  DISCARD RUBOUT OR CONTROL W
	MOVE	T2,FLLBSC	;BACKSLASH CRLF
RIFRET:	MOVSI	T1,L2LDEL	;INSIDE BACKSLASHES?
	TDNN	T1,LDBBY2(U)	; ..
	IBP	T2		;NO. SKIP BACKSLASH
	ANDCAM	T1,LDBBY2(U)	;NO LONGER IN BACKSLASHES
RIFRT1:	PUSHJ	P,SCNBOL	;SET BACK TO START OF LINE
RIDEL3:	PUSHJ	P,SETFLP	;SETUP THE FILLER POINTER
IFN FTLINK,<			;(111)
	PUSHJ	P,CHKLKF##	;(111) SEND FILL POINTER TO LINKS
>;(111)
	PUSHJ	P,TOPOKE	;START OUTPUT IF NEEDED
RIDEL2:	JRST	RINUL		;NOW DISCARD RUBOUT

;HERE ON ANY OF THE THREE ALTMODES, TO DECIDE ON CONVERSION TO STDALT
RIALT:	PUSHJ	P,RIALTO
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) PASS ON DIRECTLY
>;(110)
	JRST	RECINA
IFN FTCIMP,<			;(110)
	JRST	RECI2A		;(110)
>;(110)

RIALTO:	MOVEI	T2,(T3)		;GET A COPY OF THE CHAR.
	ANDI	T2,177		;ISOLATE CHAR (REMOVE PARITY/IMAGE/ECHO BITS)
	CAIN	T2,STDALT	;CHECK FOR TRUE ESC
	POPJ	P,
	MOVEI	T1,0		;NO, ASSUME DATA CHAR
	MOVSI	T2,LPLALT	;CONVERT OLD ALTMODES?
	TDNE	T2,LDBPAG(U)
	POPJ	P,		;NO
	MOVEI	T3,STDALT	;YES USE THE STANDARD ALTMODE
	MOVE	T1,CHTABL(T3)	;NOW A BREAK, SO GET ITS BITS
	POPJ	P,		;STORE WHATEVER THIS DECIDED ON

IFN FTSCLC,<

;RECEIVE INTERRUPT ROUTINE FOR LINE CONTROL TRANSACTIONS

;ENTER HERE FROM DEVICE-DEPENDENT ROUTINE WITH
;  TRANSACTION CODE IN T3,
;  PHYSICAL LINE # IN U (IDX FOR LINTAB, LDBDCH, ETC)
;    U'S RANGE CHECKED BY INTERRUPT ROUTINE
;  AC'S & PDL SETUP


LNCREC::MOVE	U,LINTAB##(U)
	CAIN	T3,LNTEHC	;DISPATCH ON CHARACTER CODE IN T3
	JRST	LNREHC		;ENABLE HUNG CHECK
	CAIE	T3,LNTDHC
	POPJ	P,		;ILLEGAL CODE--IGNORE

LNRDHC:	MOVEI	T3,LDRSHC	;DISABLE HUNG CHECK
	IORM	T3,LDBDCH(U)	;  TURN ON LDRSHC
	POPJ	P,

LNREHC:	MOVEI	T3,LDRSHC	;TURN OFF LDRSHC
	ANDCAM	T3,LDBDCH(U)
	POPJ	P,
> ;END OF IFN FTSCLC
IFN FTMODM,<			;CODE INCLUDED ONLY IF MODEMS SUPPORTED
;RECEIVE INTERRUPT ROUTINE FOR DATASET TRANSACTIONS

;ENTER HERE FROM DEVICE-DEPENDENT ROUTINE WITH TRANSACTION CODE IN
; T3, DSCTAB INDEX IN U, RANGE ALREADY CHECKED BY INTERRUPT
; ROUTINE, AC'S AND PDL SET UP.


DSCREC::MOVE	T2,DSCTAB##(U)	;GET TABLE ENTRY FIRST
	TLNE	T2,DSCBLI	;IGNORE INTERRUPTS?
	POPJ	P,0		;YES. DO SO.
IFN FTPI,<PUSHJ P,SIGDSC>	;SIGNAL, DATA SET STATUS CHANGE
	CAIN	T3,DSTRNG	;DISPATCH ON CODES
	JRST	DSRRNG		;RING FROM DATAPHONE
	CAIN	T3,DSTON	;CARRIER ON?
	JRST	DSRON		;YES.
IFN FTDIAL,<
	CAIN	T3,DSTPND	;DIALLER WANT ANOTHER DIGIT
	JRST	DSRPND		;YES
>
DSROFF:	CAIN	T3,DSTOFF	;OFF INTERRUPT?
	TLNN	T2,DSCHWC	;YES. DID I THINK HE WAS ON?
	POPJ	P,0		;NO. FORGET IT.
	TLNN	T2,DSCSWC	;DO I THINK HE SHOULD BE ON?
	JRST	DSROF1		;NO. JUST GO CLEAR HIM OUT.
	MOVEI	T1,5		;YES. TIME OUT IN CASE OF BRIEF FAILURE
	DPB	T1,DSTMPL	;STORE IN TIME BYTE.
	MOVSI	T1,DSCHWC	;CLEAR THE CARRIER BIT
	ANDCAM	T1,DSCTAB##(U)	; ..
	MOVSI	T1,DSCFAI	;AND FLAG POSSIBLE FAILURE CONDITION
	IORM	T1,DSCTAB##(U)	; ..
	POPJ	P,0		;LET CLOCK TIME HIM OUT NOW.
DSROF1::MOVSI	T1,DSCHWC!DSCSWC!DSCIC2
	ANDCAM	T1,DSCTAB##(U)	;CLEAR ALL THESE BITS IN TABLE
IFN FTDIAL,<
	HRRZ	T1,DSCTAB##(U)	;GET TERMINAL NUMBER FOR THIS MODEM
	CAMN	T1,DSDUNI##	;DIALLER CODE USED BY IT?
	SETOM	TTYDDL##	;YES. CLEAR INTERLOCK TO FREE IT.
>
	MOVEI	T3,DSTOFF	;AND SEND OFF-COMMAND TO DEVICE
DSCCAL::MOVE	T2,DSCTAB##(U)	;T2 ← LINE NUMBER
	MOVEI	T1,ISRDSC	;DATASET CONTROL FUNCTION
	MOVE	T2,LINTAB##(T2)	;LDB ADDRESS
	PJRST	@LDBISR(T2)	;DISPATCH TO INTERUPT SERVICE

;SUBROUTINE TO SIGNAL DATA SET STATUS CHANGE
; ENTER T3=TRANSACTION CODE
IFN FTPI,<
SIGDSC::HRRZ	T1,LINTAB##(T2)	;GET LDB ADDRESS
	HRRZ	F,LDBDDB(T1)	;GET ADDRESS OF DDB
	MOVE	T4,J		;SAVE J
	JUMPE	F,SIGDS1	;ALL DONE IF ZERO
	LDB	J,PJOBN##	;GET JOB NUMBER
	JUMPE	J,SIGDS1	;JUMP IF JOB 0 (CAN THAT HAPPEN?)
	SIGNAL	C$DSET
	  JFCL
SIGDS1:	MOVE	J,T4		;RESTORE J
	POPJ	P,		;RETURN
> ;END IFN FTPI
;STILL IN FTMODM
DSRON:
IFN FTDIAL,<
	TLNN	T2,DSCDLW	;IN DIALLER WAIT?
	JRST	DSRON1		;NO.
	MOVSI	T1,DSCDLW!DSCEON	;YES. CLEAR FLAGS FOR DIALLER
	ANDCAM	T1,DSCTAB##(U)	;IN TABLE IN CORE
	SETOM	TTYDDL##	;FREE UP DIALLER CODE
	MOVSI	T1,DSCDLC	;SET SUCCESSFUL COMPLETION BIT
	IORB	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
	PUSH	P,T2		;SAVE OLD STATUS
	PUSHJ	P,DSCWAK	;WAKE THE JOB, IF ANY STILL THERE.
	POP	P,T2		;RESTORE OLD BITS
> ;END IFN FTDIAL
DSRON1:
IFN FTCAFE,< ;CAFE'S SAY HELLO AFTER AUTOMATIC BAUD DETECT EVEN ON
;		LOCAL LINES. THIS ALLOWS USER TO GET SIGN ON MESSAGE
	HRRZ	T1,DSCTAB##(U)	;GET REAL LINE NUMBER
	HRRZ	T1,LINTAB##(T1)	;GET ADDRESS OF LDB
	MOVE	T1,LDBDCH(T1)	;GET DEVICE BITS
	TRNN	T1,LDRDSD	;IS THIS A REAL DATASET LINE?
	JRST	DSRON2		;NO--LOCAL TERMINAL JUST CAME UP
> ;END FTCAFE
	TLNE	T2,DSCHWC	;HE CAME ON. IS THAT NEWS TO ME?
	POPJ	P,0		;I THOUGHT HE WAS ON. FORGET IT.
	TLNN	T2,DSCSWC	;DO I WANT HIM ON?
	JRST	DSROF1		;NO. GO FORCE HIM OFF.
IFN FTGPO2B,<
	TLNE	T2,DSCFAI+DSCDLW	;A GPO2B MODEM CANNOT BE ALLOWED
	POPJ	P,		;TO RECOVER UNTIL THE TIMEOUT HAS
				;OCCURRED TO FORCE DETACH
				;BECAUSE 2B'S GENERATE SPURIOUS CARRIER
				;FROM DIAL TONE, BUSY, ETC.
>

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVSI	T1,DSCTMM+DSCFAI!DSCATM;(107) YES. CLEAR TIME AND FAILURE BITS
	ANDCAM	T1,DSCTAB##(U)	;IN THE TABLE (STILL IN T2)
	MOVSI	T1,DSCHWC	;MARK THAT HE CAME ON
	IORM	T1,DSCTAB##(U)	;IN TABLE
	TLNE	T2,DSCFAI+DSCDLW;WAS ALL THIS A BRIEF FAILURE?
	POPJ	P,0		;YES. JUST DISMISS, HE'S BACK.
	MOVSI	T1,DSCBLI+DSCNCR;NO. NEW GUY. SET BLIND AND DELAY BITS
	HRRZ	F,LINTAB##(T2)	;LDB
	HRRZ	F,LDBDDB(F)	;DDB
	JUMPE	F,DSRN1A	;GO IF NO DDB
	MOVE	T4,DEVMOD(F)	;CHARACTERS
	TLNN	T4,TTYATC	;IF CONSOLE
	TRNN	T4,ASSCON!ASSPRG;AND NOT ASSIGNED
DSRN1A:	TLO	T1,↑D60		;SET TIME OUT
	IORM	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
DSRON2:	HRRZ	U,LINTAB##(T2)	;GET LDB ADDRESS FOR LINE
IFN FTCIMP,<			;(110)
DSCSET:>			;(110) LABEL ADDED
	PUSHJ	P,TSETBI	;CLEAR INPUT BUFFER
IFN FTNET,<
	MOVE	T1,LDBREM(U)	;GET THE REMOTE BITS
	TLNE	T1,LRLVTM	;  AND IF THIS IS A VTM LINE,
	PUSHJ	P,VTMDSO##	;  TURN CARRIER AND QUEUE LINE FOR SERVICE
>
	MOVSI	T1,L1LOFL
	ANDCAM	T1,LDBOFL(U)
	SKIPGE	DEBUGF##
	POPJ	P,
	HRRZ	F,LDBDDB(U)	;GET DDB
	JUMPN	F,CPOPJ##	;DO NOT RUN INITIA IF THERE IS A
				; JOB ON THE LINE
	MOVEI	T1,TTFCXH	;GET HELLO COMMAND INDEX
	JRST	TTFORC		;FORCE HELLO COMMAND
> ;END CONDITIONAL ON FTMODM
TTFRC1:	AOS	(P)
TTFORC::DPB	T1,LDPCMX	;STORE FORCED COMMAND INDEX
	MOVSI	T1,LDBCMR+LDBCMF;FORCED COMMAND REQUEST.
	JRST	COMST1		;SET COMMAND COUNT, IF NEEDED

IFN FTMODM,<
DSRRNG:	MOVE	T1,STATES##	;PHONE RINGING. MAY I ANSWER?
	TRNE	T1,ST.NRL	;CHECK THE SCHEDULE COMMAND WORD
	POPJ	P,0		;NOT ALLOWED. IGNORE.
	PUSH	P,U		;SAVE PTR TO DSCTAB
	HRRZ	U,DSCTAB##(U)	;GET REAL LINE NUMBER
	HRRZ	U,LINTAB##(U)	;GET ADR OF LDB
IFN FTCAFE,<
	MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNN	T1,LDRDSD	;IS THIS A DATASET LINE?
	JRST	UPOPJ##		;NO
>;END OF IFN FTCAFE
	HRRZ	F,LDBDDB(U)	;DDB PTR
	JUMPE	F,DSRRN2	;NO JOB, ALL OK
	MOVE	T1,DEVMOD(F)	;DEVICE BITS
	TLNN	T1,TTYATC	;CONTROLLING TTY?
	JRST	DSRRN2		;NO, SO NO JOB
				;IF WE GET HERE, WE HAVE RING ON LINE
				; WITH A JOB, WHICH IS NOT SUPPOSED TO
				; HAPPEN.  TO PREVENT SECURITY PROBLEMS,
				; WE DETATCH THE JOB
	PUSHJ	P,DSCDET	;DETACH OR KILL IF NOT LOGGED IN.
DSRRN2:	POP	P,U		;RESTORE DSCTAB PTR
	MOVEI	T3,0		;CLEAR VARIOUS
	DPB	T3,DSTMPL	; TIMERS
	MOVSI	T1,DSCFAI+DSCTMM!DSCATM;(107) CLEAR THE MOMENTARY FAILURE BIT
	ANDCAM	T1,DSCTAB##(U)	; ..
	MOVSI	T1,DSCSWC+↑D30	;TURN ON ALLOW BIT, AND TIME.
DSRRN1:	IORM	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
	MOVEI	T3,DSTON	;SEND A TURN-ON COMMAND TO DEVICE-
	PJRST	DSCCAL		; DEPENDENT ROUTINE, AND DISMISS


DSCDET:	MOVEI	T1,TTFCXD	;DO THE DETACH BY
	PJRST	TTFORC		; FORCING A .BYE
IFN FTDIAL,<
DSRPND:	TLNE	T2,DSCEON	;SENT ALL DIGITS?
	POPJ	P,0		;YES. IGNORE REQUEST
	MOVEI	T1,↑D60		;ONE MINUTE FROM SENDING DIGIT
	DPB	T1,DSTMPL	;INTO TIME-OUT OF DATASET
	MOVSI	T1,DSCEON	;FLAG END OF NUMBER SENT, IF TRUE.
	ILDB	T3,TTYDDA##	;GET ANOTHER DIGIT
	CAIN	T3,17		;END OF NUMBER CODE?
	JRST	DSRPN1		;YES
	ADDI	T3,DSTPND	;CONVERT TO TRANSACTION CODE FOR XXXINT
	PJRST	DSCCAL		;AND SEND IT OUT
	

DSRPN1:	IORM	T1,DSCTAB##(U)	;SET FLAG IN TABLE
	POPJ	P,0		;DON'T SEND NUMBER
> ;END OF FTDIAL
> ;END OF FTMODM CONDITIONAL

IFE FTMODM,<DSCREC==:CPOPJ##>
	SUBTTL	KI10 CONSOLE TERMINAL SERVICE

IFN FTKI10,<
CTYINT::CONSO	TTY,40		;INPUT OR OUTPUT
	JRST	CTYOUT		;OUTPUT.
CTYIN:	DATAI	CTY,T3		;INPUT. GET THE CHARACTER
	JRST	RECINT		;GO PROCESS IT

CTYOUT:	CONO	CTY,200+SCNCHN##	;CLEAR THE OUTPUT BIT
	JRST	XMTINT		;AND GO SERVICE INTERRUPT
>;END IFN FTKI10
	SUBTTL	KS10 CTY AND KLINIK TERMINAL SERVICE

IFN FTKS10,<
CT0INT::SKIPN	.CPFEF##	;HAS FRONT END INTERRUPTED ?
	JRST	.-1		;ON THROUGH SKIP CHAIN
	WRPI	CLRCTY##	;CLEAR THE INTERRUPT
	SETZM	.CPFEF##	;CLEAR THE FLAG
	JSR	SCNSAV##	;SAVE AC'S ETC.
	MOVE	T3,KLIIWD	;GET KLINIK INPUT WORD
	TRNN	T3,KLIIVL	;IS THERE INPUT?
	  JRST	CTYIN1		;NO--PROCEED
	SETZM	KLIIWD		;YES--CLEAR IT
	MOVEI	U,KLILIN##	;GET KLINIK LINE NUMBER
	PUSHJ 	P,RECINT	;PASS TO SCNSER
CTYIN1:	MOVE	U,LINTAB+KLILIN## ;LDB FOR KLINIK LINE
	SKIPL	LDBDCH(U)	;IS KLINIK OUTPUT ACTIVE?
	SKIPE	KLIOWD		;YES--IS OUTPUT WORD AVAILABLE?
	JRST	CTYIN2		;NO--PROCEED
	MOVEI	U,KLILIN##	;KLINIK LINE NUMBER
	PUSHJ	P,XMTINT	;SEE IF MORE TO TYPE
CTYIN2:	SKIPN	T3,CTYIWD	;ANY CTY INPUT?
	  JRST	CTYIN3		;NO--PROCEED
	SETZM	CTYIWD		;YES--CLEAR IT
	MOVEI	U,CTYLIN##	;CTY LINE NUMBER
	PUSHJ	P,RECINT	;PASS TO SCNSER
CTYIN3:	MOVE	U,LINTAB+CTYLIN## ;GET LDB ADR FOR CTY
	SKIPL	LDBDCH(U)	;IS CTY TYPING ?
	SKIPE	CTYOWD		;AND IS OUTPUT WORD FREE ?
	JRST	CTYIN4		;NOT TYPING OR STILL BUSY
	MOVEI	U,CTYLIN##	;LINE NUMBER FOR CTY
	PUSHJ	P,XMTINT	;TRY TO TYPE MORE STUFF
CTYIN4:	POPJ	P,		;RETURN
>;END IFN FTKS10
	SUBTTL	FILLERS AND SIMULATION ROUTINES

;ROUTINE TO SET UP FILLERS FOR OUTPUT CHARACTERS
;CALL WITH
;	MOVE	T3,CHARACTER
;	MOVE	T1,CHTABL(T3)
;	PUSHJ	P,SETFLO
;	  <CHARACTER NEEDS FILLERS, ALREADY SETUP>
;	<CHARACTER NEEDS NO FILL>


SETFLO:	TLZ	T1,CHUAE+CHALT+CHCRE	;THESE ECHO MODES NOT USED ON OUTPUT
	TLO	T1,CHFILO	;FLAG OUTPUT-FILLER REQUEST
	JRST	SETFL2		;REST OF ROUTINE SAME AS ON INPUT

;ROUTINE TO SET FILLER POINTER FOR INPUT CHARACTERS (ECHOING)

SETFLI:	TLNE	T1,CHALT	;IS THIS A POSSIBLE ALTMODE?
	PUSHJ	P,RIALTO	;YES, SEE IF IT IS A REAL ALTMODE
;(270) this has to be handled elsewhere, since we
;(270)	can try to echo the character without getting here.
;(270)IFN FTCIMP,<			;(110)
;(270)	SKIPN	LDBIMP(U)	;(110) CROSSPATCHED TO IMP?
;(270)	JRST	SETFLX		;(110) NO.
;(270)	TLNE	T1,CHUAE!CHALT!CHSUSP;(110) YES.  IF ALT OR ↑X SUPPRESS ECHO 
;(270)	JRST	CPOPJ2##	;(110)
;(270)SETFLX:				;(110)
;(270)>;(110)
IFN FTCAFE,<
IFN FT2741,<
	MOVE	T2,LDBDCH(U)	;IS THIS A 2741
	TRNE	T2,LDR2741	; ??
	JRST	CPOPJ1##	;YES--FILLERS DONE BY PDP-11
> ;END FT2741
> ;END FTCAFE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;COMMON CODE FOR SETFLI/SETFLO

SETFL2:	MOVE	T2,LDBHPS(U)	;GET HORIZONTAL POSITION COUNTER
	TLNE	U,LDLDLR	;USER WANT DOLLAR SUPPRESSED?
	TLZ	T1,CHALT+CHUAE+CHCRE	;YES. DO SO.
	TLNE	T1,CHUAE	;WILL ↑X BE ADDED?
	ADDI	T2,2		;YES. ADD 2 TO HPOS
	TLNE	T1,CHALT	;IS IT GETTING A DOLLARSIGN?
	ADDI	T2,1		;YES. COUNT IT.
	JUMPLE	T2,SETFI1	;IF NOT AT END OF SCREEN
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) IF CROSSPATCHED, NO FREE CRLF
>;(110)
	PUSHJ	P,PTBTCH##	;CHECK FOR REGULAR PTY
	  JRST	SETFI1		;IT IS, NO FREE CRLF
	MOVE	T2,LDBDCH(U)	;GET THE CHARACTERISTICS WORD
	TLNE	T2,LDLNFC	;USER WANT FREE <CR><LF>?
	JRST	SETFI1		;NO. FORGET IT.
;	PJRST	SETCRF		;YES, FALL INTO SETCRF

;SETCRF -- ROUTINE TO SETUP A FREE CRLF POINTER

SETCRF:	PUSHJ	P,SCNBOL	;RESET LINE COUNTERS IN ANY CASE
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) NO FREE CRLF IF CROSSPATCHED
>;(110)
	TRNE	T2,LDRREM	;IS THIS A NETWORK VIRTUAL TERMINAL?
	JRST	SETCR5		;YES, THEN NO FILLER (THE REMOTE COMPUTER
				; WILL SUPPLY THE FREE <CR><LF>, WE NEED
				; MERELY NOTE THAT A NEW LINE IS STARTING)
	LDB	T2,LDPFLC	;GET FILL CLASS
SETCR2:	MOVE	T2,FLLCRP(T2)	;GET APPROPRIATE POINTER TO STRING
	PUSHJ	P,SETFLP	;SETUP THE APPROPRIATE FILLER POINTER
	MOVSI	T2,LDLLCP	;DON'T ECHO INPUT CHARACTER AFTER FREE CRLF
	TLNN	T1,CHFILO	; BUT IF OUTPUT, DON'T EAT A CHARACTER
	TDNN	T2,LDBDCH(U)	;IF LOCAL COPY IS SET
	DPB	T3,LDPSVC	;SAVE CHARACTER FOR LATER
	POPJ	P,		;NON-SKIP RETURN (NEEDED CRLF)

SETCR5:	MOVE	T2,T3		;SCRATCH COPY OF CHARACTER
	ANDI	T2,177		;JUST SEVEN-BIT ASCII
	CAIL	T2,40		;IS CHARACTER A
	CAIL	T2,177		; NORMAL PRINTING ASCII GRAPHIC?
	TLNE	T1,CHALT!CHUAE	;NO, CONTROL, IF EITHER "$" OR "↑X" FORM
	AOS	LDBHPS(U)	;THEN COUNTS AS A PRINTING CHARACTER
	TLNE	T1,CHUAE	;IN ADDITION, IF "↑X" FORM
	AOS	LDBHPS(U)	; THEN COUNTS AS TWO PRINTING CHARACTERS
	PUSHJ	P,INCPCT	;COUNT LINES OUTPUT FOR TTY PAGE N
	HLL	U,LDBDCH(U)	;GET LEFT-HALF CHARACTERISTICS
	TLNN	U,LDLSSO	;DID INCPCT HIT A PAGE BREAK?
	JRST	CPOPJ1##	;NO, JUST OUTPUT THE FIRST CHARACTER

;HERE IF THE FREE <CR><LF> THAT WE KNOW THE REMOTE IS ABOUT TO OUTPUT
;(AS SOON AS IT SEES THE CHARACTER IN T3) WILL ALSO BREAK THE PAGE LIMIT.
;WE MUST SUPPLY THE FREE <CR><LF> AND THEN STOP IN ORDER TO MAKE THE
;REMOTE BEHAVE THE SAME AS LOCALLY-OWNED TERMINALS. THIS RELYS ON THE
;FACT THAT XMTSPC WILL FORCE OUT THE FILLER POINTER EVEN IF THE LINE
;IS XOFFED - A DUBIOUS FEATURE AT BEST.

	PUSHJ	P,SCNBOL	;OOPS - RE-CLEAR HORIZONTAL POSITION

;TECHNICALLY, INCPCT SHOULD BE UNDONE, SINCE THE <CR><LF> COMING WILL
;LEAVE IT OFF BY ONE, BUT THE XON NEEDED TO GET OUT OF THE STUCK STATE
;WILL RESET THE PAGE COUNTER, SO . . .

	SETZ	T2,		;WANT JUST A <CR><LF> - THE -11 WILL PROVIDE
				; ANY FILL NEEDED.
	JRST	SETCR2		;GO OUTPUT A NEW LINE
SETFI1:	TLNN	T1,CHFIL	;THIS CHAR NEED FILLERS?
	JRST	SETFI2		;NO.
SETFI0:	PUSH	P,T3		;SAVE THE CHARACTER
				;*** CHAR MUST BE AT 0(P) FOR SIMULATORS ***
				;*** EVEN THOUGH THIS IS BAD PRACTICE
IFN FT2741&FTCAFE,<
	MOVE	T3,LDBDCH(U)	;GET LINE CHARACTERISTICS
	TRNE	T3,LDR2741	;IS THIS A 2741?
	  JRST	ZFLPOP		;YES - DC76 WILL DO FILLERS
	MOVE	T3,(P)
>;END OF IFN FT2741&FTCAFE
	ANDI	T3,177		;JUST 7 BITS (NO PARITY)
	CAIG	T3,15		;NEED TO CALL ROUTINE FOR IT?
	JRST	@SETFLD-10(T3)	;YES. GO DO IT.
	CAIL	T3,21		;CONTROL Q THRU T?
	JRST	SETFI6		;YES. THEY HAVE SPECIAL HANDLERS TOO
	PUSHJ	P,SETFLC	;GET FILL CLASS
	JUMPE	T2,ZFLPOP	;NO. USER WANT FILLER SUPPRESSED?
	SKIPA	T2,FILLP1	;NO. ASSUME ONE FILLER IS ENOUGH
ZFLPOP:	MOVEI	T2,0		;POINTER FOR NO FILLERS
FLLPOP:	PUSHJ	P,SETFLP	;SETUP THE FILLER POINTER
	JRST	CHPJ1		;RESTORE CHARACTER AND SKIP RETURN
				; SKIP IS BECAUSE T3 IS TO BE TYPED

SETFI2:	TLNN	T1,CHUAE+CHALT+CHCRE	;ECHO AS ↑X OR $ ?
	JRST	CPOPJ1##	;NO. NOTHING SPECIAL. JUST SEND.
	TLNE	T1,CHALT	;ALTMODE?
	JRST	SETFI3		;YES.
	TLNE	T1,CHCRE	;ECHO AS UPARROW X CRLF?
	JRST	SETFI4		;YES.
	TRC	T3,300		;TURN ON 100 BIT, COMPLEMENT PARITY
	DPB	T3,LDPSVC	;STORE FOR AFTER THE UPARROW
	SKIPA	T2,FLLUPA	;GET POINTER TO UPARROW CONST

SETFI3:	MOVE	T2,FLLDLR	;GET POINTER TO DOLLARSIGN GRAPHIC
	AOS	LDBHPS(U)	;ADVANCE HORIZONTAL POSITION
	PJRST	SETFLP		;SET FILLER POINTER AND RETURN
;CAN ONLY GET HERE FOR ↑U,↑Z OR ↑C. OTHERS NOT STORED IN INPUT BUFFER

SETFI4:	ANDI	T3,177		;NO PARITY
	PUSHJ	P,SCNBOL	;SET COUNTERS BACK TO BEGINNING OF LINE
	MOVEI	T2,0		;0 BYTE POINTER
	CAIN	T3,"C"-100	;CONTROL C?
	MOVE	T2,FILXCP	;YES. ITS POINTER
	CAIN	T3,"Z"-100	;CONTROL Z?
	MOVE	T2,FILXZP	;YES. ITS POINTER
	IBP	T2		;SKIP BACKSLASH
	PJRST	SETFLP		;STORE ECHO POINTER AND FORCE IT OUT

SETFI6:	TLNN	U,LDLDLR	;ECHOING GRAPHICS INHIBITED?
	TLNE	T1,CHFILO	;IS THIS FOR INPUT OR OUTPUT OF ↑Q-↑T?
	JRST	SETFI7		;NO GRAPHICS. JUST THROW ON A RUBOUT.
	MOVEI	T2,2		;LENGTH OF PRINT REPRESENTATION
	ADDM	T2,LDBHPS(U)	;ADD TO HORIZONTAL POSITION COUNTER
	MOVE	T2,STFLT2-21(T3);GET ECHO POINTER FOR CONTROL Q-T
	SOS	-1(P)		;NON-SKIP RETURN
	JRST	FLLPOP		;STORE FILLER AND RETURN

SETFI7:	PUSHJ	P,SETFLC	;GET FILL CLASS
	SKIPE	T2		;FILL 0?
	MOVE	T2,FILLP1	;NO, USE A FILLER
	PJRST	FLLPOP		;STORE FILLER AND GO HOME
;SETFLC -- ROUTINE TO SETUP THE FILLER CLASS FOR A LINE

SETFLC:	
IFN FTNET,<
	MOVEI	T2,LDRREM	;REMOTE BIT
	TDNE	T2,LDBDCH(U)	;REMOTE STATION DOES ITS OWN FILL
	TDZA	T2,T2		;SO RETURN INDEX OF ZERO
>
IFN FTCIMP,<			;(110) IF CROSSPATCHED, LET REMOTE DO IT
	SKIPN	LDBIMP(U)	;(110)
>;(110)
	PUSHJ	P,PTBTCH##	;CHECK FOR REGULAR PTY
	  TDZA	T2,T2		;IT IS, USE FILLER CLASS 0
	LDB	T2,LDPFLC	;ELSE GET FILL CLASS FROM LDB
	POPJ	P,		; AND RETURN



;ROUTINE TO SETUP AN "XON CLASS" FILLER POINTER
;CALL
;	MOVE	T2,FILL POINTER
;	PUSHJ	P,SETXNP
;	<ALWAYS RETURN HERE>

SETXNP::SCNOFF			;GET SCNSER INTERLOCK
	MOVEM	T2,LDBXNP(U)	;STORE FILL POINTER
	PJRST	SETFP1		;SET LDLFCP & RETURN



;ROUTINE TO SETUP A FILLER POINTER. SETS LDLFCP IF APPROPRIATE.
;CALL
;	MOVE	T2,FILLER POINTER
;	PUSHJ	P,SETFLP
;	<ALWAYS RETURNS HERE>
;ENTER AT SETFPT IF SCNOFF

SETFLP::SCNOFF
SETFPT::MOVEM	T2,LDBFLP(U)	;STORE IN LINE BLOCK
	JUMPE	T2,SONPPJ	;CLEARED WORD, JUST RETURN
SETFP1:	MOVSI	T2,LDLFCP
	IORM	T2,LDBDCH(U)	;SET FLAG FOR XMTCHR
	JRST	SONPPJ		;NON-SKIP RETURN, TO FORCE OUT
;DISPATCH TO SET FILLERS FOR SOME CHARACTERS

SETFLD:	EXP	FILLH,FILLI,FILLJ,FILLK,FILLL,FILLM
;POINTERS, CODE AND DATA FOR FILLER CHARACTERS

;HERE FOR A BACKSPACE AND HARDWARE VERTICAL TAB

FILLH:
FILLK2:	PUSHJ	P,SETFLC	;GET FILLER CLASS FOR LINE
	MOVE	T2,FILLHP(T2)	;GET FILLER BYTE POINTER
	JRST	FLLPOP		;GO STORE AND RETURN.

FLLFLG==:1				;FLAG TO ADD A CRLF AFTER THIS FILLER

FILXCP:	POINT	9,FILXCD	;CONTROL C ECHO
FILXCD:	BYTE	(9) 134,336,303,FLLFLG	;BACKSLASH, ↑C CRLF
FILXUP:	POINT	9,FILXUD	;CONTROL U ECHO
FILXUD:	BYTE	(9) 134,336,125,FLLFLG	;BACKSLASH, ↑U CRLF
FILXOP:	POINT	9,FILXOD	;CONTROL O ECHO
FILXOD:	BYTE	(9) 134,336,317,FLLFLG	;BACKSLASH, ↑O CRLF
FILXZP:	POINT	9,FILXZD	;POINTER TO CONTROL Z ECHO
FILXZD:	BYTE	(9) 134,336,132,FLLFLG	;BACKSLASH, ↑Z CRLF

;DISPATCH FOR ↑Q TO ↑T ECHOES

STFLT2:	POINT	9,FILXQD
	POINT	9,FILXRD
	POINT	9,FILXSD
	POINT	9,FILXTD

FILXQD:	BYTE	(9) 336,321,21,377,0	;↑Q
FILXRD:	BYTE	(9) 336,322,22,377,0	;↑R
FILXSD:	BYTE	(9) 223,336,123,0	;↑S
FILXTD:	BYTE	(9) 24,336,324,0	;↑T
FILLKP:					;POINTERS FOR BS AND VT
FILLHP:	0				;NO FILLERS
FILLP2:	POINT	9,FILLRZ,8	;2 FILLERS
	POINT	9,FILLRY,8	;6 FILLERS
	POINT	9,FILLRY,8	;6 FILLERS

FILLLP:					;POINTERS FOR FORMFEED
	0				;NO FILLERS
	POINT	9,FILLRX,26	;12 FILLERS
	POINT	9,FILLER,17	;21 FILLERS
	POINT	9,FILLER,17	;21 FILLERS

FILLJP:					;POINTERS FOR LINEFEED
	0				;NO FILLERS
FILLP1:	POINT	9,FILLRZ,17	;1 FILLER
	POINT	9,FILLRY,8	;6 FILLERS
	POINT	9,FILLRY,8	;6 FILLERS

FLLCRP::POINT	9,FLLCR0	;TABLE OF POINTERS FOR FREE CRLF'S
	POINT	9,FLLCR1
	POINT	9,FLLCR2
	POINT	9,FLLCR2

FLLCR0:	BYTE	(9) 215,12,0	;DATA FOR FREE CRLF'S
FLLCR1:	BYTE	(9) 215,215,12,377,0
FLLCR2:	BYTE	(9) 215,215,12,377,377,377,377,377,0

FLLUPA:	POINT	9,FLLUP1	;POINTER TO UPARROW
FLLDLR:	POINT	9,FLLUP1,17	;POINTER TO DOLLARSIGN
FLLUP1:	BYTE	(9) 336,0,44,0	;UPARROW AND $, WITH PARITY
FLLBSP:	POINT	9,FLLBS1	;POINTER TO BACKSLASH
FLLBS1:	BYTE	(9) 134,0,134,FLLFLG	;BACKSLASH DATA
FLLBSC:	POINT	9,FLLBS1,17	;POINTER TO BACKSLASH - CRLF

FLLCOP:	0				;FILLERS FOR OUTPUT CR
	POINT	9,FLLCO1,17	;ONE EXTRA CR
	POINT	9,FLLCO1
	POINT	9,FLLCO1
FLLCO1:
;(253)	BYTE	(9) 215,215,215,0	;EXTRA CARRIAGE RETURNS
	BYTE	(9) 377,377,377,0	;(253) EXTRA CARRIAGE fills

;DUMMY FILLER

FLLDMY:	BYTE(9)	0,0,0,0
FLLDMP:	POINT	9,FLLDMY
VT06BP:	POINT	9,VT06TB
	POINT	9,VT06TB+2,8
	POINT	9,VT06TB+4,17
	POINT	9,VT06TB+6,26
	POINT	9,VT06TB+10,35
	POINT	9,VT06TB+13,8
	POINT	9,VT06TB+15,17
	POINT	9,VT06TB+17,26

VT06EP:	POINT	9,VT06EL
	POINT	9,VT06E1
	POINT	9,VT06E2
	POINT	9,VT06E3

VTXXBP:	POINT	9,VTXXTB
	POINT	9,VTXXTB,26
	POINT	9,VTXXTB+1,17
	POINT	9,VTXXTB+2,8
	POINT	9,VTXXTB+2,35
	POINT	9,VTXXTB+3,26
	POINT	9,VTXXTB+4,17
	POINT	9,VTXXTB+5,8

VTXXEP:	POINT	9,VTXXEL
	POINT	9,VTXXE1
	POINT	9,VTXXE2
	POINT	9,VTXXE3

V100EP:	POINT	9,VTXXEL
	POINT	9,V100E1
	POINT	9,V100E2
	POINT	9,V100E3
VT06TB:	BYTE	(9)	377,377,377,210,240,377,377,377
	BYTE	(9)	210,377,377,377,210,240,377,377
	BYTE	(9)	377,210,377,377,377,210,240,377
	BYTE	(9)	377,377,210,377,377,377,210,240
	BYTE	(9)	377,377,377,210,377,377,377,210
	BYTE	(9)	240,377,377,377,210,377,377,377
	BYTE	(9)	210,240,377,377,377,210,377,377
	BYTE	(9)	377,210,240,377,377,377,210,377
	BYTE	(9)	377,377,210,240,377,377,377,210
	BYTE	(9)	0

VT06EL:	BYTE	(9)	215,377,377,377,0
VT06E1:	BYTE	(9)	30,377,377,377,0
VT06E2:	BYTE	(9)	30,377,377,377,36,377,377,377,0
VT06E3:	BYTE	(9)	215,377,377,377,36,377,377,377,0

VTXXTB:	BYTE	(9)	210,240,210,210,240,210,210,240
	BYTE	(9)	210,210,240,210,210,240,210,210
	BYTE	(9)	240,210,210,240,210,210,240,210
	BYTE	(9)	0

VTXXEL:	BYTE	(9)	215,0
VTXXE1:	BYTE	(9)	33,303,0
VTXXE2:	BYTE	(9)	33,303,33,113,0
VTXXE3:	BYTE	(9)	215,33,113,0

V100E1:	BYTE	(9)	33,333,303,0
V100E2:	BYTE	(9)	33,333,303,33,333,113,0
V100E3:	BYTE	(9)	215,33,333,113,0
;HERE TO GENERATE FILLERS OR SIMULATION FOR HORIZONTAL TAB
;PHPOS IS UPDATED ALREADY, BUT POHPOS HAS THE PREVIOUS POSITION,
;LOW ORDER THREE BITS, SO THE TAB SIMULATION CAN BE DONE FROM IT.

FILLI:
IFN FTNET,<
	MOVEI	T2,LDRREM	;REMOTE BIT
	TDNE	T2,LDBDCH(U)	;REMOTE STATION DOES OWN FILL
	JRST	ZFLPOP		;SO NO FILLERS
>
	PUSHJ	P,SETFLC	;GET FILLER CLASS
	TLNN	U,LDLTAB	;USE TAB, OR MAKE IT OUT OF SPACES?
	JRST	FILLI1		;SPACES.
	TRNN	T2,1		;FILL CLASS 0 OR 2?
	JRST	ZFLPOP		;YES, NO FILLERS
	LDB	T1,POHPOS	;GET OLD POSITION ON LINE.
	MOVE	T2,FILLP2	; ASSUME UNDER HALFWAY TO TAB STOP
	TRNE	T1,4		;TRUE?
FILL1:	MOVE	T2,FILLP1	;NO. NEED JUST ONE FILLERS.
	JRST	FLLPOP		;GO STORE FILLER POINTER, SEND
				; TAB, AND RETURN.

;HERE TO MAKE A TAB OUT OF SOME SPACES.

FILLI1:	MOVEI	T3,640		;WILL USE SPACES. DISCARD SAVED
				; TAB ON STACK.
				; IMAGE BIT BECAUSE HPOS NOW RIGHT
	LDB	T1,POHPOS	;GET LOW 3 BITS OF OLD HPOS
	MOVE	T2,FILLIP(T1)	;GET CORRESPONDING POINTER TO SPACES
	JRST	SCCHPJ		;GO STORE, TYPE FILLERS AND SVC
				; AND RETURN.

FILLJ:
	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FILLJP(T2)	;GET THE CORRESPONDING FILLERS
	JRST	FLLPOP		;FOR A LINEFEED, AND RETURN.

FILLK:	TLNE	U,LDLFRM	;THIS LINE HAVE FORM MOTION?
	JRST	FILLK2		;YES. USE SAME FILLERS AS BACKSPACE
	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FLLKSP(T2)	;GET SIMULATION POINTER
FILLK1:	MOVEI	T3,12		;CLOBBER THE VT OR FF ON STACK
SCCHPJ:	DPB	T3,LDPSVC	;SAVE CHARACTER FOR AFTER FILLERS
	PUSHJ	P,SETFLP	;SETUP THE FILLER POINTER
	JRST	T3POPJ##	;AND NON-SKIP RETURN TO CAUSE FILLERS
FILLL:	TLNE	U,LDLFRM	;THIS LINE HAVE FORM MOTION?
	JRST	FILLL1		;YES. GO SET FILLERS.
	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FLLLSP(T2)	;GET POINTER TO LINEFEEDS AND FILLERS
	JRST	FILLK1		;GO TO COMMON CODE

FILLL1:	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FILLLP(T2)	;AND FILLER POINTER
	JRST	FLLPOP		;GO STORE THIS POINTER AND RETURN

FILLM:	TLNE	T1,CHFILO	;NO, IS THIS FOR IN OR OUTPUT?
	JRST	FILLM1		;OUTPUT.
	MOVEI	T2,L2RXON	;XON BIT
	TDNE	T2,LDBBY2(U)	;XON IN EFFECT?
	JRST	ZFLPOP		;NO LOCAL, OR XON TRUE. THEREFORE,
	MOVE	T2,LDBDCH(U)	;GET DCH BITS BACK
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) CROSSPATCHED?
	TRNE	T2,LDRIMP	;(110) OR AN IMP?
	JRST	ZFLPOP		;(110) YES, LET REMOTE DO IT
>;(110)
	TDNN	T2,[XWD LDLLCP,LDRHLF]	;EITHER TYPE OF LOCAL COPY?
					; NO FREE CRLF, OR IT WILL BE ECHOED
	JRST	FILLM1		;NO LOCAL COPY
	PUSHJ	P,SETFLC	;GET FILL CLASS
	MOVE	T2,FLLCRP(T2)	;NEED A FREE LINEFEED.GET CRLF
	IBP	T2		;AND COUNT IT PAST CR
	JRST	FLLPOP		;AND GO STORE RESULT

FILLM1:	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FLLCOP(T2)	;GET FILLERS FOR CR OUTPUT
	JRST	FLLPOP		;GO STORE AND RETURN

RETYPE::
IFN FTNET,<			;IF WE HAVE THE NETWORK, WE
	SKIPGE	LDBREM(U)	; BETTER MAKE SURE THAT THIS ISN'T A VTM
	POPJ	P,		; CAUSE IF IT IS, THE CHUNKS ARE ALL
>				; MESSED UP AND WE WILL "RCC"
	SCNOFF
	SKIPN	T1,LDBBKU(U)	;SKIP IF BREAK IN BUFFER
	MOVE	T1,LDBTIT(U)	;ELSE GET START OF BUFFER
	PUSHJ	P,CTISBP	;STORE THE BYTE POINTER
	HRRZM	U,.CPCML##	;REMEMBER LINE # FOR DEBUGGING
	SCNON
RETYPL:	PUSHJ	P,CCTYI		;GET A BYTE.
				;YOU MAY THINK WE SHOULD CALL COMTYI, YOU
				; ARE WRONG.
	CAIN	T3,12		;DONE?
	JRST	[SETZM .CPCML##	;YES
		 POPJ P,0]	;RETURN
	PUSHJ	P,USEARO	;TYPE OUT CHAR, IN ARROW MODE
	JRST	RETYPL		;LOOP FOR MORE

STOPCM:	PUSH	P,T1		;SAVE T1
	MOVEI	T1,0		;GET A ZERO AND USE IT TO
	SCNOFF			;INTERLOCK W.R.T. CCTYI
	PUSHJ	P,CTISBP	;  SAY THERE IS NO COMMAND ON THIS LINE
	SCNON			;RETURN INTERLOCK
	JRST	TPOPJ##		;RESTORE T1 AND RETURN
;DATA SENT OUT AS FILLERS

FILLER:	BYTE	(9) 377,377,377,377	;BLOCK OF 23 RUBOUTS
	BYTE	(9) 377,377,377,377
FILLRX:	BYTE	(9) 377,377,377,377
	BYTE	(9) 377,377,377,377
FILLRY:	BYTE	(9) 377,377,377,377
FILLRZ:	BYTE	(9) 377,377,377,0	;ZERO TERMINATES THE STRING

KSPACE:	BYTE	(9) 240,240,240,240	;BLOCK OF 7 SPACES.
	BYTE	(9) 240,240,240,0

KLINEF:	BYTE	(9) 12,12,12,12	;BLOCK OF 7 LINEFEEDS
	BYTE	(9) 12,12,12,0

FILLIP:	POINT	9,KSPACE	;POINTERS FOR TAB SIMULATION
	POINT	9,KSPACE,8
	POINT	9,KSPACE,17
	POINT	9,KSPACE,26
	POINT	9,KSPACE,35
	POINT	9,KSPACE+1,8
	POINT	9,KSPACE+1,17
	0

FLSLD0:	BYTE	(9) 12,12,12,12	;LINEFEEDS W/O FILLERS.
FLSKD0:	BYTE	(9) 12,12,12,0	; ..

FLSLD1:	BYTE	(9) 377,377,12,377	;LINEFEEDS WITH 2 FILLERS.
	BYTE	(9) 377,12,377,377
	BYTE	(9) 12,377,377,12
FLSKD1:	BYTE	(9) 377,377,12,377
	BYTE	(9) 377,12,377,377
	BYTE	(9) 12,377,377,0
FLBPXF:	BYTE	(9) 223,0,0,0
FLLKSP:	POINT	9,FLSKD0	;POINTERS TO SIMULATE ↑K
	POINT	9,FLSKD0
	POINT	9,FLSKD1
	POINT	9,FLSKD1

FLLLSP:	POINT	9,FLSLD0	;POINTERS TO SIMULATE ↑L
	POINT	9,FLSLD0
	POINT	9,FLSLD1
	POINT	9,FLSLD1

FLBLXF:	BYTE	(9) 207,223,377,0	;DATA - BELL,XOFF,RUBOUT
FLPBEL::POINT	9,FLBLXF	;POINTER TO BELL-XOFF-RUBOUT
FLPXOF:	POINT	9,FLBLXF,8	;POINTER TO XOFF AND RUBOUT
FLPPXF::POINT	9,FLBPXF	;POINTER TO XOFF WITH NO FILL
FLLXON:	BYTE	(9) 21,377,0	;DATA - XON,RUBOUT
FLPXON:	POINT	9,FLLXON	;POINTER TO XON-RUBOUT
	SUBTTL	TIMING ROUTINE

;SUBROUTINE CALLED EVERY SECOND AT CLOCK LEVEL.
;CHECKS FOR IRMA. TIMES IMAGE INPUT. RUNS MODEMS.

SCNSEC::MOVEI	J,TCONLN##	;PREPARE TO SEARCH LINE TABLE
	PUSHJ	P,SAVE2##
IFN FTMP,<MOVE P2,.CPCPN##>	;CPU #
	SETZM	%SCNAL
SCNSIL:	MOVE	U,LINTAB##(J)	;GET ADR OF LDB
	MOVE	T1,LDBDCH(U)	;GET THE CHARACTERISTICS
IFN FTMP,<			;IF SMP, CHECK WHICH CPU WE'RE ON
	LDB	T2,LDPCPU	;GET # OF LINE'S OWNER
	TRNE	T1,LDRREM	;BUT IF IT'S A NETWORK LINE, ONLY DO
	MOVE	T2,BOOTCP##	;  TIMING ON THE BOOT CPU
	CAIE	T2,(P2)		;ARE WE ON RIGHT CPU
	JRST	SCNSIS		;IF WRONG CPU, SKIP THIS LINE
>
	TLNE	T1,LDLIMI	;IMAGE INPUT STATE?
	PUSHJ	P,SCSIMG	;YES. GO TIME IT
	MOVE	T1,LDBDCH(U)	;SCSIMG CAN CLOBBER THIS
	JUMPL	T1,SCNSIN	;IF IDLE?
	AOS	%SCNAL
IFE FTCIMP,<			;(110)
	TRNE	T1,LDRSHC!LDR2741 ;YES - HUNG CHECKING?
>;(110)
IFN FTCIMP,<			;(110)
	TRNE	T1,LDRSHC!LDR2741!LDRPTY!LDRIMP ;(110) YES - HUNG CHECKING?
>;(110)
	JRST	SCNSIN		;NO
IFN FTHDPX,<
	MOVE	T1,LDBBY2(U)	;GET HALF DUPLEX FLAGS
	TLNE	T1,L2LHD3+L2LHD4	;DURING ECHO FAILURE?
	JRST	SCNSIN		;YES. DON'T DO HUNG CHECK
>
	MOVSI	T1,LPLIRM	;SET UP SYNC BIT
	TDNE	T1,LDBPAG(U)	;ON FROM 1 SECOND AGO?
	JRST	[PUSHJ P,TOREQ	;REQUEUE SO OUTPUT STARTS
		 MOVSI	P1,L1LOFL
		 MOVEI	T1,ISROFL
		 PUSHJ	P,@LDBISR(U)
		   IORM	P1,LDBOFL(U)
		 JRST   SCNSIN]	;LOOK AT NEXT LINE
	IORM	T1,LDBPAG(U)	;TURN ON SYNC BIT FOR THIS SECOND
SCNSIN:	MOVE	T1,LDBTIC(U)
	ADD	T1,LDBECC(U)
	SKIPE	T1
	AOS	%SCNAL
	SKIPL	LDBOFL(U)
	JRST	SCNSIS
	MOVSI	P1,L1LOFL
	MOVEI	T1,ISROFL
	PUSHJ	P,@LDBISR(U)
	  SKIPA
	ANDCAM	P1,LDBOFL(U)
SCNSIS:	SOJGE	J,SCNSIL
IFN FTMP,<
	SKPCPU	(0)		;ONLY ON MASTER
	PJRST	@.CPISR##
>
	SOSGE	SNDCTR##
	SETZM	SNDCTR##
	AOS	T2,%SCNAL
	CAIGE	T2,20
	MOVEI	T2,20
	MOVE	T1,TTFREN##
	IMULI	T1,↑D12
	IDIV	T1,T2
	CAIGE	T1,↑D80
	MOVEI	T1,↑D80
	EXCH	T1,TIWRNN	;STORE NEW LIMIT AND GET PREVIOUS
	MOVEM	T1,TIWRN1	;STORE PREVIOUS
	MOVE	T1,TIWRNN	;GET NEW BACK
	CAIGE	T1,↑D600	;IF IT ISN'T AT LEAST 600
	MOVEI	T1,↑D600	; THEN MAKE IT 600
	MOVEM	T1,RPIMWN	;AND SAVE
IFE FTMODM,<PJRST @.CPISR##>	;CALL EACH ISR
				;ELSE FALL THRU INTO DATASET ROUTINE
IFN FTMODM,<

;ROUTINE TO DO ONCE-A-SECOND TIMING OF MODEMS. TIMES OUT INTERVALS
;FROM RING TO CARRIER ON, FROM CARRIER ON TO LEGAL COMMAND,
; AND FROM CARRIER OFF TO HANG UP.

DSCSEC:	SKIPL	J,DSCPTR##	;GET DATASET CONTROL POINTER
	JRST	DSCSC1		;THERE ARE NONE IN THIS CONFIGURATION
	HLLZS	J		;CLEAR RIGHT HALF FOR INDEXING
DSCSLP:	MOVE	T1,DSCTAB##(J)	;GET TABLE ENTRY
	TLNE	T1,DSCBLI	;BLIND STILL ON?
	JRST	DSCSC3		;YES.
	SCNOFF			;CAN'T ALLOW INTERRUPTS HERE
	LDB	T3,DSTIMP	;GET THE TIME SINCE RING OR CARRIER FAILURE
	SOSL	T3		;COUNT IT DOWN. WAS IT 0?
	DPB	T3,DSTIMP	;NO. STORE NEW VALUE
	JUMPN	T3,[SCNON	;UNLESS NEWLY 0, ALLOW INTERRUPTS
		    JRST DSCSNY]; AND GO TO NEXT
	MOVSI	T3,DSCFAI+DSCSWC;CLEAR FAIL AND SOFTWARE BITS
	ANDCAB	T3,DSCTAB##(J)	; IN CORE
	SCNON			;OK FOR INTERRUPTS NOW.
IFN FTDIAL,<
	TLNE	T3,DSCDLW	;IN DIALLER WAIT?
	JRST	DSCSDF		;YES. DIALLER HAS FAILED.
>
	HRRZ	U,LINTAB##(T1)	;GET THE LDB ADDRESS
				; OF THE RELATED TERMINAL LINE
IFN FTNET,<
	MOVE	T1,LDBREM(U)	;GET THE REMOTE STATUS BITS,
	TLNE	T1,LRLVTM	;  AND IF THIS IS A VTM LINE
	PUSHJ	P,VTMDSF##	;  SIGNAL CARRIER OFF TO THE REMOTE
>
	PUSHJ	P,LDBCLR	;CLEAR OUT LDB STATUS
	HRRZ	F,LDBDDB(U)	;SEE IF THERE'S A JOB.
	JUMPE	F,DSCSC2	;SKIP THIS IF NO JOB
	MOVE	T1,DEVMOD(F)	;MAY BE A JOB. GET MODE WORD.
	TLNN	T1,TTYATC	;CONTROLLING A JOB.
	JRST	DSCSC2		;NOT A CONTROLLING TERMINAL. NO COMMAND

	PUSHJ	P,DSCDET	;DETACH THE GUY (.BYE)
DSCSC2:	MOVEI	T3,DSTOFF	;SOFTWARE CODE TO TURN OFF DATASET
	MOVEI	U,0(J)		;TABLE ADDRESS AS LINE NUMBER
	PUSHJ	P,DSCCAL	;SEND TO APPROPRIATE HARDWARE DEVICE
DSCSNY:	AOBJN	J,DSCSLP	;COUNT THROUGH ALL LINES

;(107)	ADD A FEATURE TO DETACH AND HANG UP ON INACTIVE DATA-SET JOBS.
;(107)	A CHECK IS MADE ONCE EVERY <FT.DTF> SECONDS.  IF NO ACTIVITY
;(107)	AFTER THE EIGHTH CHECK, JOB IS DETACHED AND HUNG UP.  FT.DTF
;(107)	IS DEFINED IN S.MAC.

IFN	FT.DTF,<		;(107) DIAL-UP TIME-OUT FEATURE
	SOSL	DSCCLK		;(107) TIME FOR THE CHECK?
	JRST	DSCEMN		;(107) NO

DSCMIN:	MOVEI	T1,FT.DTF	;(107) YES, RESET FOR NEXT TIME
	ADDM	T1,DSCCLK	;(107)
	HLLZ	J,DSCPTR##	;(107) AOBJN POINTER

DSCMNL:	MOVE	T1,DSCTAB##(J)	;(107) LOOK AT NEXT ONE
	TLNN	T1,DSCBLI!DSCDLW!DSCTMM
				;(107) IGNORE IF THESE BITS ARE ON
				;(107) OR IF ANOTHER TIMED FUNCTION
	TLNN	T1,DSCHWC	;(107) MUST HAVE A CARRIER
	JRST	DSCMN1		;(107) ELSE, FORGET IT
	LDB	T2,DSTTOP	;(107) GET TIMEOUT FIELD
	SOSGE	T2		;(107) DECREMENT.  NEGATIVE YET?
	PUSHJ	P,DSCZAP	;(107) YES, DETACH AND HANG UP
	DPB	T2,DSTTOP	;(107) DEPOSIT DECREMENTED COUNT
DSCMN1:	AOBJN	J,DSCMNL	;(107) LOOP FOR THEM ALL
DSCEMN:!			;(107) THAT'S ALL
>;(107)	END ON IFN FT.DTF CONDITIONAL

DSCSC1:	PJRST	@.CPISR##	;DO ISR TIMING
;STILL IN FTMODM
IFN	FT.DTF,<		;(107) DIAL-UP TIMEOUT FEATURE
;(107)	DSCTOR - RESET TIME-OUT FIELD FOR ACTIVITY TESTING TO 7
;(107)	USES ONLY REGISTER T1

DSCTOR:				;(107) DIAL-UP TIMEOUT RESET
	MOVE	T1,LDBDCH(U)	;(107) GET LINE CHARACTERISTICS
	TRNN	T1,LDRDSD	;(107) DATA-SET LINE?
	POPJ	P,		;(107) NO, RETURN
	PUSH	P,J		;(107) YES, SAVE AN AC
	LDB	J,LDPDSC	;(107) GET DSCTAB INDEX INTO J
	MOVEI	T1,7		;(107) IT'S A 3-BIT FIELD
	DPB	T1,DSTTOP	;(107) RESET FIELD TO 7
	POP	P,J		;(107) RESTORE J
	POPJ	P,		;(107) RETURN
>;(107)	END ON IFN FT.DTF CONDITIONAL

DSCZAP:	HRRZ	U,LINTAB##(T1)	;(1) GET DDB ADR
	PUSHJ	P,DSCDET	;(1) DETACH IT
	MOVEI	T3,DSTOFF	;(1) SOFTWARE CODE TO TURN OFF
	MOVEI	U,0(J)		;(1) DATA-SET NUMBER
	PJRST	DSCCAL		;(1) SEND TO APPROPRIATE HARDWARE
DSCSC3:	MOVSI	T3,DSCBLI	;SET FOR BLIND BIT
	TLNE	T1,DSCNCR	;NEW CARRIER BIT STILL ON?
	MOVSI	T3,DSCNCR	;YES. CLEAR IT INSTEAD
	ANDCAM	T3,DSCTAB##(J)	;CLEAR BIT IN TABLE
	JRST	DSCSNY		;AND GO ON TO NEXT MODEM

IFN FTDIAL,<
DSCSDF:	SETOM	TTYDDL##	;CLEAR DIALLER CODE INTERLOCK
	MOVEI	U,0(J)		;COPY TABLE INDEX
	PUSHJ	P,DSROF1	;CLEAR OUT THE HARDWARE FOR THIS LINE.
	MOVSI	T1,DSCDLF	;FLAG THAT DIALLING LOST
	IORB	T1,DSCTAB##(J)	; ..
	PUSHJ	P,DSCWAK	;WAKE THE SLEEPING JOB, IF ANY
	JRST	DSCSNY		;LOOK FURTHER THRU DSCTAB

DSCWAK:	MOVE	T1,LINTAB##(T1)	;GET THE LDB ADDRESS FOR THIS DATASET'S TERMINAL
	HRRZ	F,LDBDDB(T1)	;GET THE DDB, IF ANY
	SKIPE	T1		;ANY?
	LDB	T1,PJOBN##	;YES. GET JOB NUMBER
	JUMPE	T1,CPOPJ##	;ANY?
	PJRST	WAKJOB##	;YES. WAKE IT.
> ;END OF FTDIAL

;(1)  WMU PATCH TO HANG UP LINES AFTER 60 SECONDS OF INACTIVITY
DSCOUT::JUMPE	U,CPOPJ##	;(1) EXIT IF NO LDB
	PUSHJ	P,CHKDSD	;(1) MAKE SURE IT IS A REAL DATASET
	  POPJ	P,		;(1) NOT A DATASET. EXIT.
	LDB	T1,LDPDSC	;(1) GET DSCTAB OFFSET
	LDB	T2,DSTLBT	;(1) GET TIME-OUT FIELD
	JUMPN	T2,CPOPJ	;(1) EXIT IF NOT ZERO
	MOVEI	T2,↑D60		;(1) SET TO 60
	DPB	T2,DSTLBT	;(1) SO LINE WILL HANG UP
	POPJ	P,		;(1) AFTER 60 SECONDS OF INACTIVITY

;(1)  SUBROUTINE TO CHECK THAT A TTY IS A REAL DATASET
;(1)	USAGE
;(1)		MOVE	U,LDB-ADR
;(1) 		PUSHJ	P,CHKDSD
;(1)		  NOT DATASET RETURNS HERE
;(1)		DATASET RETURNS HERE

CHKDSD:	PUSH	P,T1		;(1) SAVE T1
	MOVE	T1,LDBDCH(U)	;(1) GET LDB STATUS
	SKIPGE	DSCPTR##	;(1) ANY DATASETS CONFIGURED?
	TRNN	T1,LDRDSD	;(1) YES. IS THIS SUPPOSED TO BE ONE?
	  JRST	TPOPJ##		;(1) NO. EXIT
	PUSH	P,T2		;(1) SAVE T2 ALSO
	LDB	T2,LDPDSC	;(1) GET OFFSET INTO DSCTAB
	LDB	T1,LDPLNO	;(1) AND GET LINE NUMBER OF TTY
	XOR	T1,DSCTAB(T2)	;(1) IS IT SAME AS DSCTAB ENTRY?
	POP	P,T2		;(1) RESTORE T2
	TRNE	T1,-1		;(1) IF NOT, RIGHT HALF WILL BE NON-ZERO
	  JRST	TPOPJ		;(1) WRONG? GET OUT NOW!
	JRST	TPOPJ1##	;(1) REAL LIVE DATASET! SKIP RETURN



;(110) SUBROUTINE CALLED ONCE A MINUTE ON THE CLOCK TO LOOK
;(110) FOR LOST TELETYPE DDB'S AND RETURN THEM.  APPLIES TO IMP ITY'S AND DATASETS.
IFN FTCIMP,<
SCNMIN::MOVEI	F,TTYLST	;(110) POINT TO FIRST TTY DDB
SCNMN1:	PUSHJ	P,TTYKLQ	;(110) RETURN DDB IF LOST
	HLRZ	F,DEVSER(F)	;(110) ADVANCE TO NEXT DDB
	MOVE	T3,DEVMOD(F)	;(110) IS IT A TTY?
	TLNE	T3,DVTTY	;(110) ....
	JRST	SCNMN1		;(110) YES - KEEP ON TRUCKING
	POPJ	P,		;(110) NO - EXUENT OMNI
> ;(110) END FTCIMP
DSTLBT:	POINT	6,DSCTAB##(T1),17	;(1) TIME BYTE POINTER INDEXED BY T1
DSTIMP:	POINT	6,DSCTAB##(J),17	;POINTERS TO TIME BYTE
DSTMPL:	POINT	6,DSCTAB##(U),17	;SAME BUT DIFFERENT AC INDEX
				;MUST AGREE WITH DSCTMM
IFN	FT.DTF,<		;(107)
DSTTOP:	POINT 3,DSCTAB##(J),11	;(107) DATA-SET TIMEOUT FIELD
>;(107)
> ;END OF FTMODM


IFN FTCIMP,<			;(110)

;(110) SUBROUTINE TO CLEAR OUT LDB,DDB UPON LOSING A CONNECTION.
;(110)    APPLIES BOTH TO IMP AND DDB CONNECTIONS. ENTER WITH U
;(110)    POINTING TO DDB IN QUESTION.

DSCCLR:	SKIPE	F,LDBIMP(U)	;(110) CROSSPATCHED TO IMP?
	PUSHJ	P,TTIDET##	;(110) YES - PULL THE PLUG
	PUSHJ	P,LDBCLR	;(110) CLEAN OUT LDB STATUS
IFN FTLINK,<			;(111)
	PUSHJ	P,LNKBRK##	;(111) SHAKE OFF ANY EXISTING LINKS
>;(111)
	PUSHJ	P,TSETBI	;(110) CLEAR INPUT
	PUSHJ	P,TSETBO	;(110)  AND OUTPUT BUFFERS
	HRRZ	F,LDBDDB(U)	;(110) SEE IF THERE'S A JOB
	JUMPE	F,CPOPJ##	;(110) NO
	MOVE	T1,DEVMOD(F)	;(110) MAY BE A JOB. GET MODE WORD
	TLNN	T1,TTYATC	;(110) IS TTY CONTROLLING A JOB?
	POPJ	P,		;(110) NOT A CONTROLLING TTY
	SKIPE	T1,F
	LDB	T1,PJOBN	;(110) GET JOB NUMBER
	MOVE	T2,JBTSTS##(T1)	;(110) GET JOB STATUS
	TLNN	T2,JLOG		;(110) IS JOB LOGGED IN?
	JRST	DSCCL1		;(110) NO - STOP JOB BY SENDING REAL CTRL-C
	MOVEI	T3,TTFCXD	;(110) DETACH COMMAND INDEX
	DPB	T3,LDPCMX	;(110) STORE IN FORCED COMMAND INDEX BYTE
	MOVSI	T3,LDBCMR+LDBCMF ;(110) SET FORCED COMMAND BIT
	IORM	T3,(U)		;(110) FOR COMMAND SCANNER TO SEE
	AOS	COMCNT##	;(110) WAKE COMMAND DECODER
	PJRST	CMDSET		;(110) CALL COMMAND ROUTINE

;(110) HERE IF NOT LOGGED IN. SET ↑O BIT AND SEND ↑C, FOR PROGRAM TO
;(110)  INTERPRET AS IT WILL (IE, KILL LOGIN)
DSCCL1:	MOVSI	T1,LDLCOM 	;(110) CLEAR COM LEVEL BIT, SET ↑O BIT
	HRRI	T1,LDROSU	;(110)
	XORM	T1,LDBDCH(U)	;(110) (COM WAS SET BY LDBCLR)
	MOVEI	T3,"C"-100	;(110) SET UP A CTRL-C
	PJRST	RECIN1		;(110) JAM IT INTO INPUT
> ;(110) END IFN FTCIMP

;SUBROUTINE TO TIME THE IMAGE MODE INPUT STATE, SET END OF FILE IF
;IT TIMES OUT, AND FORCE CONTROL C UNLESS SLAVED ON SECOND TIME-OUT


SCSIMG:	PUSH	P,J		;SAVE COUNTER. WILL BE CLOBBERED.
	LDB	T3,LDPTIM	;GET THE IMAGE TIME BYTE
	SOSL	T3		;COUNT IT DOWN. TOO LOW?
	DPB	T3,LDPTIM	;NO STORE NEW VALUE.
	JUMPG	T3,IPOPJ##	;IF NO TIMEOUT YET, GO BACK TO LOOP
	HRRZ	F,LDBDDB(U)	;GET LINE'S JOB DATA BLOCK
	JUMPE	F,SCSIM2	;NO JOB? TIME AGAIN
IFN FTCIMP,<			;(110)
	MOVEI	T1,INDSTM	;(110) HAS USER DISABLED IMAGE MODE TIMEOUT?
	TDNE	T1,DEVIOS(F)	;(110) ...
	JRST	IPOPJ##
>;(110)
	MOVSI	S,FRCEND	;CAUSE UUO ROUTINE TO FORCE END
	TDNE	S,DEVIOS(F)	;ON YET?
	JRST	SCSIM1		;ON ALREADY. PANIC.
	IORB	S,DEVIOS(F)	;NO. SET IT NOW AND TIME OUT AGAIN
SCSIM2:	MOVEI	T3,IMGTIM	;SET TIME TO NEXT PANIC
	DPB	T3,LDPTIM	;STORE IN TIME BYTE
	PUSHJ	P,RCVWAK	;AND WAKE UP JOB
	JRST	IPOPJ##		;GO RESTORE J AND RETURN

SCSIM1:	MOVSI	S,TTYATC	;GET A BIT
	TDNE	S,DEVMOD(F)	;IS THIS AN I/O DEVICE?
	TLNE	T1,LDLSLV	;IS THIS A SLAVE TERMINAL?
	JRST	SCSIM2		;YES. CAN'T DO CONTROL C
	PUSHJ	P,CNCMOD	;NO. SET TO COMMAND LEVEL
	MOVSI	T1,LDBCMF	;FORCE COMMAND
	DPB	T1,LDPCMX	;CONTROL C INDEX
	IORM	T1,LDBDDB(U)	;AND FLAG COMMAND DECODER
	PUSHJ	P,COMSET	;WAKE UP COMMAND ROUTINE,
	JRST	IPOPJ##		;RESTORE AC AND RETURN
;OUTPUT SERVICE ROUTINE FOR CTY

IFN FTKI10!FTKS10,<
CTYSTO::MOVEI	T1,.CPCTQ##	;POINT TO CTY OUTPUT QUEUE HEADER
	PUSHJ	P,TOTAKE	;GET A LINE NUMBER (CHECK QUEUE)
	  POPJ	P,		;NONE WAITING
	SKIPGE	LDBDCH(U)
	PUSHJ	P,XMTCHR	;GET NEXT OUTPUT CHARACTER
	  POPJ	P,		;LINE IS NOW IDLE
	PUSHJ	P,CLRIRM	;CLEAR IRMA BH
CTYTYO:	ANDI	T3,377		;REMOVE JUNK
IFN FTKI10,<
	DATAO	CTY,T3		;SEND THE CHARACTER
>
IFN FTKS10,<
	MOVE	T1,LINTAB##+KLILIN##
	CAIN	U,(T1)		;KLINIK LINE?
	JRST	KLITYO		;YES--GO TO IT
	IORI	T3,CTYOVL	;SET VALID FLAG
	MOVEM	T3,CTYOWD	;PUT IN OUTPUT WORD
CTYTY1:	RDAPR	T1		;GET CPU PI LEVEL
	ANDI	T1,SP.PIA	; AND ONLY THE PI LEVEL
	WRAPR	SP.SSF+SP.IFE(T1) ;INTERRUPT THE 8080
>
IFN FTHDPX!FTTRACK,<
	DPB	T3,LDPECK	;FOR LIGHTS ONLY (CTY IS FDX)
>
	POPJ	P,0		;AND RETURN
IFN FTKS10,<
KLITYO:	IORI	T3,KLIOVL	;SET VALID BIT
	MOVEM	T3,KLIOWD	;PUT CHAR IN OUTPUT WORD
	JRST	CTYTY1		;GO INTERRUPT 8080
>;END IFN FTKS10
>;END IFN FTKI10!FTKS10
;ROUTINE TO ADJUST HORIZONTAL POSITION COUNT FOR CHARACTER TO
;OUTPUT FROM BUFFER. CALL WITH T3, U SET UP.

ADJHP:	PUSH	P,T3		;SAVE CHARACTER
	ANDI	T3,177		;JUST CHARACTER BITS
	CAIL	T3,177		;RUBOUT
	JRST	T3POPJ##	;DOESN'T SPACE
	CAIL	T3,40		;NON-IMAGE CONTROL CHARACTER?
	JRST	ADJHP1		;NO, SIZE IS ONE
	PUSH	P,T2
	CAIN	T3,11		;IS THIS A TAB?
	JRST	ADJHP2		;YES, GO FIGURE OUT HOW BIG IT IS
	CAIN	T3,15		;CARRIAGE RETURN?
	JRST	ADJHP3		;SETS HPOS BACK TO START
	CAIE	T3,10		;BACKSPACE?
	JRST	T23PPJ		;NO, OTHER DON'T CHANGE HPOS
	PUSHJ	P,HPOS		;GET CURRENT POSITION
	JUMPE	T2,T23PPJ	;IF AT START OF LINE
	SOS	LDBHPS(U)	;ELSE DECREMENT POSITION BY ONE
	JRST	T23PPJ		;AND RETURN

;HERE FOR CARRIAGE RETURN

ADJHP3:	PUSHJ	P,SCNBOL	;BACK TO START OF LINE
	JRST	T23PPJ		;AND RETURN

;HERE FOR TAB

ADJHP2:	PUSHJ	P,HPOS		;CURRENT HORIZONTAL POSITION
	DPB	T2,POHPOS	;SAVE LOW 3 BITS FOR SIMULATION
	ANDI	T2,7		;ISOLATE (POSITION MOD 8)
	MOVN	T2,T2		; -(POSITION MOD 8)
	ADDI	T2,10		; 8-(POSITION MOD 8)
	ADDM	T2,LDBHPS(U)	;FIX HPOS COUNTER
	JRST	T23PPJ		;AND RETURN

;HERE FOR PRINTING CHARACTER

ADJHP1:	AOSA	LDBHPS(U)	;INCREMENT POSITION
T23PPJ:	POP	P,T2
	JRST	T3POPJ##
;HPOS -- SUBROUTINE TO FETCH THE CURRENT HORIZONTAL POSITION ON A LINE
;CALL
;	PUSHJ	P,HPOS
;	<ALWAYS RETURN HERE>
;EXIT WITH T2 = HORIZONTAL POSITION.  PRESERVES ALL OTHERS AC'S.

HPOS::	LDB	T2,LDPWID	;GET CARRIAGE WIDTH
	ADD	T2,LDBHPS(U)	;COMPUTE HORIZONTAL POSITION
	POPJ	P,		;AND RETURN IT


;ROUTINE TO SET A LINE BACK TO THE BEGINNING

SCNBOL:	PUSH	P,T2		;SAVE ALL AC'S
	LDB	T2,LDPWID	;GET WIDTH
	MOVNM	T2,LDBHPS(U)	;INITIAL VALUE OF HORIZONTAL POS COUNTER
	MOVEI	T2,0
	DPB	T2,POHPOS	;INITIAL LOW ORDER 3 BIT COUNTER
	JRST	T2POPJ##	;RESTORE T2 AND RETURN
;ROUTINE TO SUPPRESS BLANK LINES
IFN FTTBLK,<

BLSUPI:	PUSHJ	P,HPOS		;GET HORIZONTAL POSITION
	HRLI	T2,LPLSLF	;  (LPLSLF BIT IN LH)
	TRZE	T2,-1		;ANYTHING ON THIS LINE?
	ANDCAM	T2,LDBPAG(U)	;YES - CLEAR BIT TO ALLOW L.F.
	PUSH	P,T3		;SAVE CHARACTER
	ANDI	T3,177		;REDUCE TO 7-BIT ASCII
	CAIL	T3,12		;IS CHARACTER LF, VT, OR FF?
	CAILE	T3,14		; . . .
	JRST	T3POPJ##	;NO
	IORM	T2,LDBPAG(U)	;SET BIT TO SUPPRESS LF'S
	JRST	T3POPJ##	;BUT ALWAYS ECHO INPUT <CR><LF>S

BLSUPO:	PUSHJ	P,HPOS		;GET HORIZONTAL POSITION
	HRLI	T2,LPLSLF	;  (LPLSLF BIT IN LH)
	TRZE	T2,-1		;ANYTHING ON THIS LINE?
	ANDCAM	T2,LDBPAG(U)	;YES - CLEAR BIT TO ALLOW L.F.
	PUSH	P,T3		;SAVE CHARACTER
	ANDI	T3,177		;REDUCE TO 7-BIT ASCII
	CAIL	T3,12		;IS CHARACTER LF, VT, OR FF?
	CAILE	T3,14		; . . .
	JRST	T3POPJ##	;NO
	CAIN	T3,12		;YES-SUPPRESS LF?
	TDNN	T2,LDBPAG(U)
	SKIPA	T3,[12]		;NO-TURN VT OR FF INTO LF
	MOVEI	T3,0		;YES-TURN LF INTO NULL
	IORM	T2,LDBPAG(U)	;SET BIT TO SUPPRESS LF'S
	MOVE	T1,CHTABL(T3)	;GET BITS FOR NEW CHARACTER
	POP	P,T2		;RESTORE OLD CHARACTER
	TRNE	T2,200		;PARITY/VTM ECHO BIT?
	TRO	T3,200		;YES, ADD IT
	POPJ	P,
> ;IFN FTTBLK
;SUBROUTINE TO WAKE UP JOB IF IT IS IN TERMINAL INPUT WAIT. CALL WITH
;LINE SET UP. IT WILL SET DDB AND S AS NEEDED.

RCVWAK:				;(110)
IFN FTCIMP,<			;(110)
	SKIPE	F,LDBIMP(U)	;(110) CROSSPATCHED TO IMP?
	PJRST	TTIMPI		;(110) YES, HANDLE DIFFERENTLY
>;(110)
	HRRZ	F,LDBDDB(U)	;GET ADDRESS OF ATTACHED DDB
	JUMPE	F,CPOPJ##	;IF NONE,SKIP THIS CODE
	PUSH	P,T1		;SAVE T1
	LDB	T1,PJOBN##	;GET JOB NUMBER OF TERMINAL OWNER
	MOVSI	S,TTILCE##	;IS JOB ENABLED FOR WAKE UP
	TDNE	S,JBTRTD##(T1)	;DURING A HIBERNATE
	JRST	WAKJB		;YES, GO WAKE JOB
WAKJBR:	POP	P,T1		;RESTORE T1
	MOVE	S,DEVIOS(F)	;GET STATUS OF TERMINAL FROM DDB
IFN FTPI,<TLZ S,IO>		;MAKE SURE BIT IS RIGHT
	TLNE	S,IOW		;JOB IN I/O WAIT FOR TERMINAL?
	TLNE	S,TTYOUW	;YES. FOR INPUT WAIT?
IFN FTPI,<JRST PSIIOD##>	;GENERATE PSI SO USER WILL KNOW I/O IS DONE
IFE FTPI,<POPJ P,0>		;NO--DON'T WAKE JOB.

TTWAKE::PUSH	P,T1		;SAVE VOLATILE AC'S
	PUSH	P,T2		; ..
	LDB	T1,PJOBN##	;IS JOB # IN DDB ZERO?
	JUMPE	T1,TTWAKX	;EXIT IF ZERO
	MOVE	S,DEVIOS(F)	;MAKE SURE S IS CORRECT
IFN FTPSCD,<
	MOVE	T1,LDBDCH(U)	;LINE CHARACTERISTICS
	JUMPL	S,TTWAKO	;OUTPUT?
TTWAKI:	TRNE	T1,LDRPTY	;INPUT. PTY?
	AOSA	%PISJB##	;YES
	  AOS	%TISJB##	;NO
	JRST	TTWAKB
TTWAKO:	TRNE	T1,LDRPTY	;OUTPUT. PTY?
	AOSA	%POSJB##	;YES
	  AOS	%TOSJB##	;NO
TTWAKB:>
	MOVEI	S,IOACT		;CLEAR I/O ACTIVE
	ANDCAB	S,DEVIOS(F)	;IN DDB FOR THIS JOB
	PUSHJ	P,STTIOD##	;CALL STTIOD FOR TERMINALS, PTYS
TTWAKX:	POP	P,T2		;RESTORE AC'S
	PJRST	TPOPJ##		;RETURN FROM RCVWAK

;ROUTINE TO SEE IF CHARACTER SPECIAL HANDLING SHOULD BE SUPPRESSED
;PRESERVES T1

FULLCQ:	PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  TLNN	U,LDLBKA+LDLFCS	;NO. DOES USER WANT ALL CHARACTERS?
	AOS	(P)		;NO. COMMAND OR NOT SMART USER
	POPJ	P,0		;SMART USER. NON-SKIP RETURN.
WAKJB:	PUSH	P,T2		;SAVE AC'S
	PUSH	P,T3
	MOVSI	T2,(JS.HIB)	;IS JOB SLEEPING
	TDNE	T2,JBTST2##(T1)	;OR HIBERNATING?
	PUSHJ	P,WAKJOB##	;HIBERNATING: WAKE THE JOB
	POP	P,T3		;RESTORE THE AC'S
	POP	P,T2
	JRST	WAKJBR		;RETURN TO NORMAL PROGRAM FLOW

;THE FOLLOWING ROUTINE IS CALLED BY THE HIBERNATE UUO TO
;PUT THE TERMINAL INTO CHARACTER MODE.  T1 IS PRESERVED.

HIBTTY::PUSH	P,T1		;SAVE T1
	PUSHJ	P,TTYFND	;FIND THIS JOB'S TTY
	JUMPE	U,TPOPJ##	;NO TERMINAL FOR THIS JOB
	MOVSI	T1,TTIACE##	;HIBERNATE IN CHARACTER MODE?
	TDNN	T1,JBTRTD##(J)
	JRST	HIBTTL		;NO, IT MUST BE LINE MODE
	PUSHJ	P,TTCCHK	;CHECK IF A CHARACTER IS ALREADY PRESENT
	  JRST	TPOPJ##		;NO LINE, ECHO STARTED
HIBSET:	MOVSI	T1,WAKEB##	;LINE OR CHARACTER PRESENT
	IORM	T1,JBTRTD##(J)	;DON'T HIBERNATE
	PJRST	TPOPJ##		;RESTORE T1 AND RETURN (TO UUOCON)
HIBTTL:	PUSHJ	P,TTLCHK	;CHECK FOR A LINE PRESENT
	  JRST	TPOPJ##		;NO LINE, ECHO STARTED
	JRST	HIBSET		;YES, DON'T GO TO SLEEP

;TABLE OF CONTROL CHARACTERS - LH=BITS, RH=DISP ADDR ON RCV INT

;DEFINITION OF BITS IN THIS TABLE
CHBRK==:1	;THIS IS A BREAK CHARACTER
CHUAE==:2	;THIS CHARACTER ECHOES AS ↑X
CHFIL==4	;THIS CHARACTER REQUIRES FILLERS AT SOME SPEEDS
CHALT==10	;THIS CHARACTER IS ONE OF THE THREE ALTMODES.
CHRIA==20	;THIS CHARACTER REQUIRES RCV INT LEVEL ACTION
CHCRET==40	;THIS IS A CARRIAGE RETURN (NEEDED FOR SETFLO)
CHCNC==100	;THIS IS CONTROL C
CHDEL==200	;THIS IS DELETE
CHFILO==400	;BIT ADDED FOR OUTPUT FILLER ROUTINE (NOT IN TABLE)
CHCRE==1000	;THIS CHARACTER GETS CRLF AFTER ITS ↑ X ECHO
CHVPOS==2000	;VERT. POSITIONING SIMULATED WITH FORM FEEDS
CHEPAR==:4000	;THIS BIT SET IF CHARACTER IS EVEN PARITY
CHDELW==10000	;THIS IS A CONTROL W
CHPUNC==20000	;THIS IS A PUNCTUATION CHARACTER
IFN FTCIMP,<			;(110)
CHXPIH==40000	;(110) SPECIAL HANDLING EVEN IF CROSSPATCHED TO IMP
CHSUSP==100000	;(110) SUPPRESS ECHO IF SPECIAL ACTION SUPPRESSED
>;(110)
IFE FTCIMP,<			;(110)
CHXPIH==0	;DEFINED, BUT HAVE NO EFFECT
CHSUSP==0	;DITTO
>;(110)
CHSPO==400000	;REQUIRES SPECIAL CHECKING ON OUTPUT.  MUST BE THE
		;SIGN BIT.

CHTABL:	XWD	CHSPO+CHRIA+CHEPAR+CHPUNC,RINUL			;↑@ NUL 000
IFN FTMIC,<
	XWD	CHSPO+CHRIA+CHUAE+CHPUNC,RICA			;↑A SOH 001
	XWD	CHSPO+CHRIA+CHUAE+CHPUNC,RICB			;↑B STX 002
>
IFE FTMIC,<
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑A SOH 001
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑B STX 002
>
	XWD	CHSPO+CHUAE+CHBRK+CHRIA+CHCRE+CHCNC+CHEPAR+CHPUNC,RICC	;↑C ETX 003
	XWD	CHSPO+CHUAE!CHRIA+CHPUNC,RICD			;↑D EOT 004
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑E ENQ 005
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑F ACK 006
	XWD	CHSPO+CHBRK+CHPUNC,0				;↑G BEL 007
	XWD	CHSUSP+CHSPO+CHBRK+CHRIA+CHPUNC,RIBSP		;(110)↑H BS 010
	XWD	CHSPO+CHFIL+CHEPAR,0				;↑I HT  011
	XWD	CHSPO+CHFIL+CHBRK+CHEPAR+CHPUNC,0		;↑J LF  012
	XWD	CHSPO+CHFIL+CHBRK+CHVPOS+CHPUNC,0		;↑K VT  013
	XWD	CHSPO+CHFIL+CHBRK+CHVPOS+CHEPAR+CHPUNC,0	;↑L FF  014
	XWD	CHXPIH+CHSPO+CHRIA+CHFIL+CHCRET+CHPUNC,RICM		;↑M CR  015
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑N SO  016
	XWD	CHSPO+CHUAE+CHRIA+CHCRE+CHEPAR+CHPUNC,RICO	;↑O SI  017
IFN FTMIC,<
	XWD	CHSPO+CHRIA+CHUAE+CHPUNC,RICP			;↑P DLE 020
>
IFE FTMIC,<
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑P DLE 020
>
	XWD	CHSPO+CHUAE+CHFIL+CHRIA+CHEPAR+CHPUNC,RICQ	;↑Q XON 021
	XWD	CHSPO+CHUAE+CHFIL+CHRIA+CHBRK+CHEPAR+CHPUNC,RICR;↑R TAPE 022
	XWD	CHSPO+CHUAE+CHRIA+CHFIL+CHPUNC,RICS		;↑S XOFF 023
	XWD	CHSPO+CHUAE+CHFIL+CHRIA+CHBRK+CHEPAR+CHPUNC,RICT;↑T- NTAPE 024
	XWD	CHSUSP+CHSPO+CHUAE+CHRIA+CHCRE+CHBRK+CHPUNC,RICU ;(110)↑U NAK 025
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑V SYN 026
	XWD	CHSUSP+CHSPO+CHUAE+CHRIA+CHEPAR+CHPUNC+CHDEL+CHDELW+CHBRK,RIDEL ;(110)↑W ETB 027
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑X CAN 030
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑Y EM  031
	XWD	CHSPO+CHUAE+CHBRK+CHCRE+CHPUNC,0		;↑Z SUB 032
	XWD	CHSUSP+CHSPO+CHBRK+CHALT+CHRIA+CHEPAR+CHPUNC,RIALT ;(110)↑[ ESC 033
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑\ FS  034
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑] GS  035
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑↑ RS  036
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑← US  037

		0						;SPACE	040
	XWD	CHEPAR+CHPUNC,0					;!	041
	XWD	CHEPAR+CHPUNC,0					;"	042
	XWD	CHPUNC,0					;#	043
	XWD	CHEPAR+CHPUNC,0					;$	044
	XWD	CHPUNC,0					;%	045
	XWD	CHPUNC,0					;&	046
	XWD	CHEPAR+CHPUNC,0					;'	047
	XWD	CHEPAR+CHPUNC,0					;(	050
	XWD	CHPUNC,0					;)	051
	XWD	CHPUNC,0					;*	052
	XWD	CHEPAR+CHPUNC,0					;+	053
	XWD	CHPUNC,0					;,	054
	XWD	CHEPAR+CHPUNC,0					;-	055
	XWD	CHEPAR+CHPUNC,0					;.	056
	XWD	CHPUNC,0					;/	057
	XWD	CHEPAR,0					;0	060
		0						;1	061
		0						;2	062
	XWD	CHEPAR,0					;3	063
		0						;4	064
	XWD	CHEPAR,0					;5	065
	XWD	CHEPAR,0					;6	066
		0						;7	067
		0						;8	070
	XWD	CHEPAR,0					;9	071
	XWD	CHEPAR+CHPUNC,0					;:	072
	XWD	CHPUNC,0					;;	073
	XWD	CHEPAR+CHPUNC,0					;<	074
	XWD	CHPUNC,0					;=	075
	XWD	CHPUNC,0					;>	076
	XWD	CHEPAR+CHPUNC,0					;?	077
	XWD	CHPUNC,0					;@	100
	XWD	CHEPAR,0					;A	101
	XWD	CHEPAR,0					;B	102
		0						;C	103
	XWD	CHEPAR,0					;D	104
		0						;E	105
		0						;F	106
	XWD	CHEPAR,0					;G	107
	XWD	CHEPAR,0					;H	110
		0						;I	111
		0						;J	112
	XWD	CHEPAR,0					;K	113
		0						;L	114
	XWD	CHEPAR,0					;M	115
	XWD	CHEPAR,0					;N	116
		0						;O	117
	XWD	CHEPAR,0					;P	120
		0						;Q	121
		0						;R	122
	XWD	CHEPAR,0					;S	123
		0						;T	124
	XWD	CHEPAR,0					;U	125
	XWD	CHEPAR,0					;V	126
		0						;W	127
		0						;X	130
	XWD	CHEPAR,0					;Y	131
	XWD	CHEPAR,0					;Z	132
	XWD	CHPUNC,0					;[	133
	XWD	CHEPAR+CHPUNC,0					;/	134
	XWD	CHPUNC,0					;]	135
	XWD	CHPUNC,0					;↑	136
	XWD	CHEPAR+CHPUNC,0					;←	137

;THESE LETTERS ARE LOWER-CASE
	XWD	CHEPAR+CHPUNC,0					;`	140
		0						;a	141
		0						;b	142
	XWD	CHEPAR,0					;c	143
		0						;d	144
	XWD	CHEPAR,0					;e	145
	XWD	CHEPAR,0					;f	146
		0						;g	147
		0						;h	150
	XWD	CHEPAR,0					;i	151
	XWD	CHEPAR,0					;j	152
		0						;k	153
	XWD	CHEPAR,0					;l	154
		0						;m	155
		0						;n	156
	XWD	CHEPAR,0					;o	157
		0						;p	160
	XWD	CHEPAR,0					;q	161
	XWD	CHEPAR,0					;r	162
		0						;s	163
	XWD	CHEPAR,0					;t	164
		0						;u	165
		0						;v	166
	XWD	CHEPAR,0					;w	167
	XWD	CHEPAR,0					;x	170
		0						;y	171
		0						;z	172
	XWD	CHEPAR+CHPUNC,0					;{	173
	XWD	CHPUNC,0					;|	174

;THE 3 HIGH SPECIALS
	XWD	CHSPO+CHRIA+CHEPAR+CHALT+CHPUNC,RIALT		;}      175
	XWD	CHSPO+CHRIA+CHEPAR+CHALT+CHPUNC,RIALT		;}      176
	XWD	CHSUSP+CHSPO+CHBRK+CHRIA+CHDEL+CHPUNC,RIDEL	;(110)   DEL 177
TTPWID:	POINT	8,TCRTAB(T1),7	;POINTER TO TERMINAL WIDTH
TTPPSZ:	POINT	6,TCRTAB(T1),13	;POINTER TO PAGE SIZE
TTPFLC:	POINT	2,TCRTAB(T1),35	;POINTER TO DEFAULT FILL CLASS
TTPFRM:	POINT	1,TCRTAB(T1),14	;ON IF TERMINAL HAS HARDWARE FORM FEEDS
TTPTAB:	POINT	1,TCRTAB(T1),15	;ON IF TERMINAL HAS HARDWARE TABS
TTPLCT:	POINT	1,TCRTAB(T1),16	;ON IF TERMINAL DOESN'T HAVE LOWER CASE CHARACTERS
TTPALT:	POINT	1,TCRTAB(T1),17	;ON IF NO ALTMODE CONVERSION IS REQUIRED
TTPDIS:	POINT	1,TCRTAB(T1),18	;ON IF "DISPLAY" TERMINAL (E.G., FOR DDT)

DEFINE	TERMCR(NAME,WIDTH,LENGTH,FF$,TAB$,LC$,ALT$,DIS$,FILL,BPERAS,BPRUBO),<
X1==0
IFIDN <FF$><FF>,<X1==1>
X2==0
IFIDN <TAB$><TAB>,<X2==1>
X3==1
IFIDN <LC$><LC>,<X3==0>
X4==1
IFIDN <ALT$><ALT>,<X4==0>
X5==0
IFIDN <DIS$><DIS>,<X5==1>
IFNDEF TT'NAME,<TT'NAME:>BYTE	(8)WIDTH(6)LENGTH(1)X1(1)X2(1)X3(1)X4(1)X5(15)0(2)FILL
	XWD	BPERAS,BPRUBO	;<CR> EOL,,B.S. SPACE B.S.
>
CTCTAB:			;CUSTOMER TERMINAL CHARACTERISTICS GO HERE
TERMCR	LA34,↑D132,0,NOFF,TAB,LC,NOALT,NODIS,0,0,0
TCRTAB:			;SEE TTTWDT IN COMCON
TERMCR	TTY,↑D72,0,NOFF,NOTAB,NOLC,ALT,NODIS,1,0,0
TERMCR	VT05,↑D72,↑D20,NOFF,TAB,NOLC,NOALT,DIS,2,VT06EP,VTXXBP
TERMCR	VT06,↑D72,↑D25,NOFF,NOTAB,NOLC,NOALT,DIS,1,VT06EP,VT06BP
TERMCR	VT50,↑D80,↑D12,NOFF,TAB,NOLC,NOALT,DIS,0,VTXXEP,VTXXBP
TERMCR	VT52,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,VTXXEP,VTXXBP
TERMCR	VT61,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,VTXXEP,VTXXBP
TERMCR	DAS21,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,VTXXEP,VTXXBP
TERMCR	VT100,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,V100EP,VTXXBP
TERMCR	TY33,↑D72,0,NOFF,NOTAB,NOLC,ALT,NODIS,1,0,0
TERMCR	TY35,↑D72,0,FF,TAB,NOLC,ALT,NODIS,1,0,0
TERMCR	LA30,↑D72,0,NOFF,NOTAB,NOLC,NOALT,NODIS,1,0,0
TERMCR	LA36,↑D132,0,NOFF,NOTAB,LC,NOALT,NODIS,0,0,0
TERMCR	2741,↑D128,0,NOFF,NOTAB,LC,NOALT,NODIS,3,0,0
TERMCR	LA38,↑D132,0,NOFF,TAB,LC,NOALT,NODIS,0,0,0
TERMCR	LA120,↑D132,0,FF,TAB,LC,NOALT,NODIS,0,0,0
;ROUTINE TO CHECK FOR A SPECIAL CHARACTER AND SET T1 TO ITS DESCRIPTOR
;ENTER WITH T3 SET UP
;SKIPS IF CHAR IS 0-37 OR 175-177
;IGNORES AND DOES NOT RETURN PARITY BIT (CHEPAR)


CHPJ1:	AOSA	-1(P)		;SKIP RETURN WITH T3 FROM STACK
	MOVEI	T1,0		;NON-SPECIAL T1
	JRST	T3POPJ##	;AND RESTORE T3 AND RETURN


SPCHEK::MOVE	T1,T3		;COPY CHAR
	ANDI	T1,177		;CLEAR PARITY
	TRNE	T3,400
	TDZA	T1,T1
	MOVE	T1,CHTABL(T1)	;GET TABLE ENTRY
	TLZ	T1,CHEPAR+CHPUNC;CLEAR PARITY AND PUNCTUATION BIT
	SKIPE	T1		;SPECIAL?
	AOS	(P)		;YES--SKIP
	POPJ	P,		;RETURN


;SUBROUTINE TO GET EVEN PARITY USING CHEPAR BIT OF CHTABL
;CALLED FROM SCNSER,PTPSER AND IN ONCE

;CALLING SEQUENCE:  PUSHJ	P,PEVEN8

;ON ENTRY, T3 CONTAINS A CHARACTER IN BITS 28 TO 35,
; BITS 0 TO 27 ARE IGNORED

;ON EXIT, BIT 28 IS CHANGED IF NECESSARY SUCH THAT THE PARITY
; OF BITS 28 TO 35 IS EVEN, AND BITS
; 0 TO 27 ARE ALL 0

PEVEN8::ANDI	T3,177		;CLEAR TO 7 BITS FOR INDEX
	PUSH	P,T1		;SAVE T1
	MOVE	T1,CHTABL(T3)	;GET CHARACTER TABLE ENTRY
	TLNN	T1,CHEPAR	;ALREADY EVEN
	TRO	T3,200		;WAS NOT, PUT IN PARITY BIT
	JRST	TPOPJ		;RESTORE T1 AND RETURN
	SUBTTL	CHUNK HANDLERS

;The routines NEWCKI and NEWCKO are provided only to support the
;macros LDCHK, LDCHKR, and STCHK.  They should not be called directly
;because they depend on the instruction following the call to be a 
;byte instruction that references the byte pointer into the chunk
;string.

;NEWCKO -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN PUTTING CHARACTERS
;	  INTO THE TERMINAL BUFFER CHUNKS.

NEWCKO::PUSH	P,@(P)		;SAVE ADDRESS OF THE BYTE INSTRUCTION
	HRRZ	T2,@(P)		;ADDRESS OF LAST BYTE IN CHUNK
	MOVEI	T2,CK.BTH##(T2)	;ADDRESS OF CURRENT CHUNK HEADER
	HRRZ	T1,(T2)		;IS THERE A CHUNK THERE YET?
	JUMPN	T1,[EXCH T1,T3
		    PUSHJ P,RCCCHK
		    EXCH T1,T3
		    JRST NWCKO1]
	PUSHJ	P,GETCHK	;ALLOCATE A CHUNK FROM FREE LIST
	HRLZM	T2,(T1)		;BACK POINTER TO EXISTING LIST
	HRRM	T1,(T2)		;FORWARD POINTER TO NEW CHUNK
NWCKO1:	ADD	T1,[POINT 9,1]	;MAKE A BYTE POINTER
	MOVEM	T1,@(P)		;STORE IN STRING POINTER
	SUB	P,[1,,1]	;PRUNE PUSH DOWN LIST
	POPJ	P,		;AND RETURN

;NEWCKI -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN TAKING CHARACTERS
;	   OUT OF THE TERMINAL CHUNKS.  USES T2 AND T3.

NEWCKI::PUSH	P,@(P)		;SAVE ADDRESS OF THE BYTE INSTRUCTION
	HRRZ	T3,@(P)		;ADDRESS OF LAST BYTE
	MOVEI	T1,CK.BTH##(T3)	;ADDRESS OF CHUNK HEADER
	HRRZ	T3,CK.BTH##(T3)	;FORWARD CHUNK POINTER
	PUSHJ	P,RCCCHK
	HRRZS	(T3)		;CLEAR BACK POINTER
	PUSHJ	P,FRECHK	;FREE UP THE STALE CHUNK
	ADD	T3,[POINT 9,1]	;MAKE FORWARD POINTER INTO A BYTE PTR
	MOVEM	T3,@(P)		;STORE IT BACK IN POINTER WORD
	SUB	P,[1,,1]	;PRUNE PUSH DOWN LIST
	POPJ	P,		;AND RETURN
;NEWCKS -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN TAKING CHARACTERS
;	   OUT OF THE TERMINAL CHUNKS.  DIFFERS FROM NEWCKI IN THAT THE
;	   STALE CHUNKS ARE NOT DELETED.

NEWCKS:	PUSH	P,@(P)		;SAVE ADDRESS OF THE BYTE INSTRUCTION
	HRRZ	T3,@(P)		;ADDRESS OF LAST BYTE
	MOVEI	T1,CK.BTH##(T3)	;ADDRESS OF CHUNK HEADER
	HRRZ	T3,CK.BTH##(T3)	;FORWARD CHUNK POINTER
	PUSHJ	P,RCCCHK
	ADD	T3,[POINT 9,1]	;MAKE FORWARD POINTER INTO A BYTE PTR
	MOVEM	T3,@(P)		;STORE IT BACK IN POINTER WORD
	SUB	P,[1,,1]	;PRUNE PUSH DOWN LIST
	POPJ	P,		;AND RETURN

CL0STP:	STOPCD .,STOP,CL0,	;++CHUNK LINKS TO ZERO

RCCCHK:	PUSH	P,T3		;SAVE ALL
	CAML	T3,TTBASE	;IF TOO LARGE
	CAMLE	T3,RCCMAX##	; OR TOO SMALL
	PUSHJ	P,RCCSTP	;
	ANDI	T3,CK.BDY	;JUST OFFSET WITHIN CHUNK
	CAIE	T3,1		;MUST BE ONE
	PUSHJ	P,RCCSTP	;ISN'T, DIE
	HLRZ	T3,@(P)		;ADDRESS OF PREDECESSOR
	HRRZ	T3,(T3)		; SHOULD POINT TO US
	CAME	T3,(P)		;...
	PUSHJ	P,RCCSTP	;DOESN'T, CHUNKS AE MESSED UP
	JRST	T3POPJ##	;RESTORE T3 AND RETURN
	SUBTTL	CHUNK HANDLERS -- ALLOCATION AND DEALLOCATION

;FRECHK and GETCHK are called to return and fetch chunks from the
;SCNSER chunk free chain.  The chain is maintained in first-in first-out
;order in order to preserve as much information for crash analysis as
;possible.  The oldest chunk is pointed to by TTFTAK, while the youngest
;is pointed to by TTFPUT.  To aid in reconstruction of the events
;leading to a crash, the left half of each chunk header contains the LDB
;address of the line that last used it.

GETCKZ:	PUSHJ	P,GETCHK	;GET A FREE CHUNK
	SETZM	(T1)		;ZERO THE LINK WORD
	POPJ	P,		; AND RETURN

GETCHK:	SKIPN	T1,TTFTAK	;CHECK THE FREE LIST
	STOPCD	.,STOP,FLE,	;++FREE LIST EMPTY
	PUSH	P,T2		;SAVE T2
	HRRZ	T2,(T1)		;TO NEXT CHUNK
	MOVEM	T2,TTFTAK	;STORE POINTER TO NEW FIRST CHUNK
	SOS	TTFREN##	;COUNT DOWN NUMBER OF FREE CHUNKS
	JUMPN	T2,T2POPJ##	;IF NOT LAST CHUNK, RETURN
	MOVEI	T2,TTFTAK	;MAKE TTFPUT POINT AT TTFTAK SO
	MOVEM	T2,TTFPUT	; FRECHK WILL RELINK THE POINTERS CORRECTLY
	JRST	T2POPJ##	; AND RETURN

FRECHK:	HRLZM	U,(T1)		;MARK LINE NUMBER IN CHUNK
	HRRM	T1,@TTFPUT	;STORE CHUNK AT END
	HRRZM	T1,TTFPUT	;POINT TO NEW ENTRY.
	AOS	TTFREN##	;COUNT UP NUMBER OF CHUNKS
	POPJ	P,
	SUBTTL	CHUNK HANDLERS -- CLEAR BUFFERS

;ROUTINES TO CLEAR INPUT AND OUTPUT BUFFERS

TSETBI::TRNN	U,-1
	STOPCD	.,STOP,LNS,	;++LINE NOT SETUP
	PUSHJ	P,STOPCM
	SCNOFF
TSETI2:	SETZM	LDBTIC(U)	;CLEAR COUNTS
	SETZM	LDBECC(U)	;OF INPUT CHARACTERS
	MOVE	T1,LDBTIT(U)	;MOVE PUTTERS BACK TO TAKER
	MOVEM	T1,LDBTIP(U)
	MOVEM	T1,LDBECT(U)	;NO ECHOING EITHER
	SETZM	LDBBKU(U)
	SETZM	LDBBKC(U)	; ..
	MOVEI	T1,L2RECS	;CLEAR BIT IN LDB WHICH
	ANDCAM	T1,LDBBY2(U)	; MIGHT CAUSE A LINE TO BE SKIPPED
	SCNON
	PJRST	CHKXON		;CHECK IF AN XON MUST BE SENT OUT AND EXIT

TSETBO::
IFN FTTPAG,<
	MOVSI	T1,LDLSTP+LDLSSO;CLEAR OUTPUT STOP BIT
	ANDCAM	T1,LDBDCH(U)	;OUTPUT CAN NOW HAPPEN AGAIN
>
	SCNOFF			;NO PI'S HERE
IFN FTMIC&FTMLOG,<
	SKIPE	LDBLOT(U)
	JRST	MICLGC
> ;END OF FTMLOG CONDITIONAL
	SETZM	LDBTOC(U)	;NO OUTPUT CHARACTERS LEFT
	MOVE	T1,LDBTOT(U)	;PUT PUTTER BACK AT TAKER
	MOVEM	T1,LDBTOP(U)	; ..
	MOVEI	T3,-1(T1)	;ADDRESS PART OF POINTER
	TRZ	T3,CK.BDY	;ADDRESS OF CHUNK HEADER MINUS ONE.
	HRRZ	T1,1(T3)	;ADDRESS OF FIRST CHUNK IN CHAIN TO DELETE
	JUMPE	T1,TSETB2	;IF NULL CHAIN
	SETZM	1(T3)		;CLEAR POINTER TO CHAIN BEFORE DELETION
TSETB1:	HRRZ	T3,(T1)		;POINTER TO CHUNK FOLLOWING CURRENT
	PUSHJ	P,FRECHK	;DELETE ONE CHUNK
	MOVEI	T1,(T3)		;NEXT CHUNK ON CHAIN
	JUMPN	T1,TSETB1	;LOOP TO END OF CHAIN
TSETB2:
	SCNON			;ALL'S CLEAR NOW
	MOVEI	T3,3		;ISR CODE FOR CHAR GOBBLER
	MOVEI	T1,ISRREM	;SPECIAL ISR ENTRY FOR REMOTES
	PJRST	@LDBISR(U)	;SEND MESSAGE TO CLEAR OUTPUT BUFFER IN REMOTE

RCCSTP:	STOPCD	.,STOP,RCC,	;++RANGE CHECKED CHUNK
	SUBTTL	UUO LEVEL ROUTINES FOR BUFFERED I/O

;DISPATCH TABLE FOR UUO'S AND INITIALIZATION

	JRST	ECOD2##		;NO DEVOP FUNCTIONS
	JRST	REGSIZ##	;BUFFER SIZE CAN BE GOTTEN FROM DDB
	JRST	TTYINI##(P2)	;INITIALIZATION (140 RESTART)
	JRST	CPOPJ1##	;HUNG DEVICE (NEVER USED)
SCNDSP::JRST	TTYREL		;RELEASE
	JRST	OUT##		;CLOSE OUTPUT
	JRST	TTYOUT		;TTY OUTPUT UUO
;	JRST	TTYIN		;TTY INPUT UUO
;FALL INTO TTYIN
;INPUT UUO PROCESSOR - CALLED FROM UUOCON ON INPUT UUO, DDB SET UP


TTYIN:	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSHJ	P,CKATTI	;MAKE SURE ATTACHED. SET S.
	MOVEI	T1,DEPAIO	;IS THIS TERMINAL IN ASYNC INPUT
	TDNN	T1,DEVAIO(F)	; MODE?
	JRST	TTYINA		;NO--FORGE AHEAD
	PUSHJ	P,TTICHK	;IS THERE ANY INPUT AVAILABLE?
	  POPJ	P,0		;NO--RETURN NOW
TTYINA:	TRNN	S,I		;IMAGE MODE?
	JRST	TTYIN0		;NO. SKIP SETUP STUFF
	TRNN	S,IODERR	;EOF DUE TO ↑C ON UNATTACHED LINE?
	TLNE	S,FRCEND	;CLOCK ROUTINE WANT IT FINISHED?
	JRST	TTYIN9		;YES. GO DO SO.
	MOVE	T1,DEVMOD(F)	;IS THIS GUY ALLOWED IMAGE MODE INPUT?
	TRNN	T1,ASSCON	;I.E., HE HAS TERMINAL ASSIGNED?
	JRST	TTYINE		;NO. ERROR BIT TO USER.
	MOVSI	T1,LDLIMI	;YES. SET IMAGE INPUT IN LINE DATA
	IORM	T1,LDBDCH(U)	; ..
	PUSHJ	P,SETCHP	;MAKE SURE THAT THE FRONT END KNOWS
TTYIN0:	PUSHJ	P,TWAITI	;BECOME ATTACHED, WAIT FOR INPUT
				; OR FULL BUFFER CONDITION
	TLNE	S,FRCEND	;DID WE TIME OUT AT CLOCK
	JRST	TTYIN9		;LEVEL WHILE WAITING ?
TTYIN5:	HRRZ	T1,DEVIAD(F)	;PREPARE AND ADDR CHECK THE
	PUSHJ	P,BUFCLR##	; USER'S BUFFER
	  JRST ADRERR##		;OUT OF BOUNDS. STOP JOB.
	HRRZ	P1,DEVIAD(F)	;USER VIRTUAL ADDRESS OF BUFFER
	EXCTUX	<LDB P2,[POINT 17,@P1,17]>  ;SIZE OF BUFFER (DATA + 1)
	SUBI	P2,1		;LESS THE .BFCNT WORD
	HRRZ	U,DDBLDB(F)	;RESTORE LINE, CLOBBERED IN UUOCON
	PUSHJ	P,SRLPTR	;SETUP BYTE COUNT AND POINTER
	PUSH	P,P2		;SAVE BYTE COUNT
				;FALL INTO MAIN PART OF ROUTINE
TTYIN1:	PUSHJ	P,TYICC		;GET A CHARACTER
	  JRST TTYIN3		; END OF BUFFER.
	MOVE	P3,T3		;COPY CHARACTER
	ANDI	P3,377		;STRIP IMAGE BIT
	EXCTUU	<IDPB P3,P1>	;AND STORE IN USER AREA
	TRNN	S,I!PIMMOD	;SKIP IF IMAGE MODE OF SOME SORT
	JRST	TTYIN2		;NO, ASCII MODE
	SOJG	P2,TTYIN1	;YES, JUST FILL BUFFER
	JRST	TTYIN3		;BUFFER FULL, GIVE IT TO THE USER

TTYIN2:	TLNN	T1,CHBRK	;A BREAK?
	SOJG	P2,TTYIN1	;NO. LOOP FOR MORE, IF ROOM.
	MOVSI	S,IOEND		;COUNTED OUT, OR BREAK.
	MOVE	T1,DEVIOS(F)	;GET USER MODE BITS
	TRZ	T3,200		;STRIP OFF PARITY, NOT IMAGE.
	TRNN	T1,IOSTEC	;TRUTH-IN-ECHOING MODE AND
	CAIE	T3,"Z"-100	;END OF FILE CHARACTER?
	MOVEI	S,0		;NO. NOT EOF.
	IORB	S,DEVIOS(F)	;STORE IN DDB S WORD
TTYIN3:	POP	P,T1		;GET BACK ORIGINAL MAX BYTE COUNT
	TRNN	S,PIMMOD	;BYTE COUNT IF PIM
	SKIPA	P2,DEVIAD(F)	;NOT PIM - BUFFER PTR IN P2
	SKIPA			;PIM - DON'T DESTROY BYTE COUNT
	JRST	TTYINC		;NOT PIM-WORD COUNT
	MOVN	P1,P2		;COUNT OF BYTES LEFT
	ADD	P1,T1		;FROM MAX = COUNT OF BYTES DEPOSITED
	SKIPA	P2,DEVIAD(F)	;ALREADY HAVE COUNT IN P1
TTYINC:	SUBI	P1,1(P2)	;COMPUTE WORD COUNT FOR UUOCON
	EXCTUU	<HRRM P1,1(P2)>	;STORE WITH DATA IN RING
	PUSHJ	P,ADVBFF##	;ON TO NEXT BUFFER
	  JRST	TTYIN8		;NO MORE BUFFERS AVAILABLE
	TRNE	S,I!PIMMOD	;IMAGE MODE?
	SKIPG	LDBTIC(U)	;AND MORE CHARACTERS TO READ?
	JRST	TTYIN8		;NO - ASCII, ONLY PASS ONE LINE AT A TIME
	JRST	TTYIN5		;YES. GO PASS SOME MORE

TTYIN8:	MOVSI	S,IOFST		;SET VIRGIN BUFFER BIT
TTYINX:	IORB	S,DEVIOS(F)	;IN DEV S WORD IN DDB
	HRRZ	U,DDBLDB(F)
	JUMPE	U,CPOPJ##
	PJRST	NOCTRO		;CLEAR CONTROL O. END OF UUO

;HERE IF ATTEMPT TO PUT UNASSIGNED TERMINAL IN IMAGE INPUT STATE

TTYINE:	MOVEI	S,IOIMPM
	JRST	TTYINX		; AND RETURN

TTYIN9:	MOVSI	S,IOEND		;SET END OF FILE BIT IN S
	JRST	TTYINX
;OUTPUT UUO CALLS HERE

;CALLED ON OUTPUT OR OUTPUT CLOSE, FROM UUOCON, WITH DDB SET UP.


TTYOUT:	PUSHJ	P,SAVE2##	;SAVE P1-P2
IFN FTRSP,<PUSHJ P,RSPTOR##>	;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
	TRNE	S,IODERR	;↑C TYPED AT TTYNNN
	JRST	TTOUT3		;YES, RETURN
	PUSHJ	P,CKATOU	;FIRST, MAKE SURE THERE'S A
				; PHYSICAL LINE ATTACHED TO JOB, AT USER LEVEL
	TRNN	S,I		;UNLESS IMAGE MODE,
	PUSHJ	P,CLRIMI	;CLEAR IMAGE INPUT STATE
	MOVSI	S,IOBEG		;IS THIS THE FIRST BUFFER AFTER INIT?
	TDNN	S,DEVIOS(F)	;CHECK DDB
	JRST	TTOUT1		;NO.
	ANDCAM	S,DEVIOS(F)	;YES. CLEAR BEG BIT,
	PUSHJ	P,NOCTRO	; AND CONTROL O
TTOUT0:	SETZM	DEVSTS(F)	;CLEAR OLD PARTIAL BYTE POINTER IF ANY

;OUTPUT A BUFFER OF TEXT. AT THIS POINT WE COULD CHECK FOR ↑O IN EFFECT
;AND JUST EAT THE BUFFER, BUT WE DON'T WANT ↑O TO BE TOO FAST . . .

TTOUT1:	MOVE	S,[IO!IOFST,,IOACT]	;MARK START OF NEW OUTPUT
	IORB	S,DEVIOS(F)	;IN DEVICE DATA BLOCK
	HRRZ	P1,DEVOAD(F)	;USER VIRTUAL ADDRESS OF OUTPUT BUFFER
	HRRZ	T1,P1		;CHECK ADDRESSES OF OUTPUT BLOCK
	PUSHJ	P,BRNGE##	;MAKE SURE BUFFER IS ADDRESSABLE
	EXCTUX	<HRRZ P2,1(P1)>	;SIZE OF DATA AREA (WORDS) TO BE OUTPUT
	JUMPE	P2,TTOUT6	;SKIP THIS BUFFER IF EMPTY
	EXCTUX	<LDB T1,[POINT 17,@P1,17]>  ;GET TOTAL BUFFER SIZE
	CAML	P2,T1		;DATA CONTAINED WITHIN BUFFER?
	JRST	TTYINE		;NO, USER BLEW IT
				; (IT ALSO MIGHT IME US!)
	PUSHJ	P,SRLPTR	;GET BYTE COUNT AND POINTER
	SKIPN	DEVSTS(F)	;OUTPUT PENDING?
	JRST	TTOUT2		;NO, NEW BUFFER
	MOVE	P1,DEVSTS(F)	;YES, GET LAST OUTPUT POINTER
	LDB	P2,BYTCNT	;AND REMAINING BYTE COUNT
				; AND FINISH (MAYBE) OUTPUTTING THE BUFFER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;LOOP OUTPUTTING CHARACTER FROM THE USER BUFFER

TTOUT2:	PUSHJ	P,CKROOM	;SEE IF WE SHOULD CALL TYO
	  JRST	TTOUT7		;IO WAIT WOULD HAPPEN
	EXCTUX	<ILDB T3,P1>	;GET A USER'S CHARACTER
	ANDI	T3,377		;KEEP JUST THE CHARACTER
	MOVEI	T1,DEPAIO	;IF DOING ASYNCHRONOUS I/O,
	TDNE	T1,DEVAIO(F)	; TELL TYO NOT TO BLOCK SINCE
	TLO	T3,(1B0)	; WE MAY BE HERE FORM TTMORE
	TRNE	S,I!PIMMOD	;SEE IF IMAGE MODE OR PIM
	TROA	T3,400		;YES. SET BIT FOR SUPPRESSING FILLERS
	JUMPE	T3,TTOUT5	;DON'T OUTPUT NULLS
	TRNE	S,IODERR	;↑C TYPED ON TTYNNN
	JRST	TTOUT3		;YES, RETURN
	PUSHJ	P,TYO9W		;OUTPUT THIS CHARACTER (WAIT IF NEEDED)
TTOUT5:	SOJG	P2,TTOUT2	;COUNT USER'S ITEMS.
TTOUT6:	PUSHJ	P,ADVBFE##	;ADVANCE HIS BUFFERS
	  JRST	TTOUT3		;JUST SINGLE BUFFER FOR NOW
	MOVEI	T1,DEPAIO	;NON-BLOCKING I/O BIT
	TDNE	T1,DEVAIO(F)	;DOING NON-BLOCKING I/O
	JRST	TTOUT0		;YES, START THE NEXT BUFFER OUT
TTOUT3:	SETZM	DEVSTS(F)
	MOVEI	S,IOACT		;CLEAR ACTIVE BIT.
	ANDCAB	S,DEVIOS(F)	;IN DEVICE DATA BLOCK FOR THE JOB
	POPJ	P,0		;END OF UUO. RETURN TO USER

TTOUT7:	MOVEM	P1,DEVSTS(F)	;SAVE THE INTERRUPTED BYTE POINTER
	DPB	P2,BYTCNT	; AND ITS COUNTER
	MOVEI	T1,JS.NTO	;SET THE MAGIC
	IORM	T1,JBTSTS##(J)	; BIT IN JBTSTS
	MOVEI	S,IOACT		;CLEAR I/O ACTIVE BIT
	ANDCAB	S,DEVIOS(F)	;..
	POPJ	P,0		;RETURN
TTMORE::PUSHJ	P,SAVE2##	;SAVE P1-P2
	MOVEI	F,SCNDDB	;FIRST DDB
	MOVEI	P2,JS.NTO	;FLAG RESET
	MOVE	T1,.CPPC##	;GET THE CURRENT PC
	TLNE	T1,USRMOD	;IN USER MODE?
	MOVEM	T1,.JDAT+JOBPD1##	;YES--MAKE SURE JOBPD1 IS RIGHT
MORE10:	LDB	T1,PJOBN##	;GET OWNER
	CAIN	T1,(J)		;IS IT THIS JOB?
	SKIPN	DEVSTS(F)	;IS OUTPUT WAITING?
	JRST	MORE20		;NO, TRY NEXT DDB
	MOVEI	T1,DEPAIO
	TDNN	T1,DEVAIO(F)	;NON-BLOCKING I/O ON THIS TERMINAL?
	JRST	MORE20		;NO, LOOK AT OTHER TERMINALS
	PUSHJ	P,MORE30	;GO TRY OUTPUT
	MOVEI	P2,0		;FLAG ONE ACTIVE
MORE20:	HLRZ	F,DEVSER(F)	;PICK UP NEXT DDB
	MOVSI	T1,DVTTY	;IS THIS A TTY?
	TDNE	T1,DEVMOD(F)	; ..
	JUMPN	F,MORE10	;YES--LOOK AT IT TOO
	ANDCAM	P2,JBTSTS##(J)	;CLEAR THE STATUS
	POPJ	P,0		;RETURN
MORE30:	HRRZ	U,DDBLDB(F)	;GET ADDRESS OF LDB
	JUMPE	U,CPOPJ##	;PUNT IF DETACHED
	MOVE	S,DEVIOS(F)	;SET UP S FOR TYO
	LDB	P1,BYTCNT	;GET THE BYTE COUNT
	JUMPE	P1,MORE41	;IF BYTE COUNT=0 AND DEVSTS NON-0, BUFFER WASN'T ADVANCED
				; BECAUSE WHAT DEVOAD POINTED TO WAS PAGED OUT

MORE40:	PUSHJ	P,CKROOM	;ROOM FOR MORE DATA?
	  JRST	[DPB P1,BYTCNT	;NO--SAVE BYTE COUNT
		 POPJ P,0]	;RETURN
	MOVE	T1,DEVSTS(F)	;GET POINTER
	IBP	T1		;UPDATE POINTER
	TLZ	T1,-1		;CLEAR JUNK
	PUSHJ	P,IADRCK##	;MAKE SURE ITS LEGAL AND IN CORE
	  JRST	MORE50
	EXCTUX	<ILDB T3,DEVSTS(F)>  ;GET THE NEXT BYTE
	TLO	T3,(1B0)	;AVOID BLOCKING IN TYO
	TRNE	S,I!PIMMOD	;IF IMAGE OR PIM
	TROA	T3,400		;FLAG IT
	TRNE	T3,-1		;SKIP CALL IF NO CHARACTER
	PUSHJ	P,TYO9W		;TYPE IT
	SOJG	P1,MORE40	;DO THE NEXT BYTE
MORE41:	HRRZ	T1,DEVOAD(F)	;BUF APR
	SOS	T2,T1		;WORD-1
	ADDI	T2,3		;THRU WORD1
	PUSHJ	P,ZRNGE##	;IN CORE?
	  JRST	MORE50		;NO

IFN FTPI,<
	TLO	S,IO		;FORCE FLAG TO OUTPUT
	PUSHJ	P,PSIIOD##
>
	JRST	TTOUT6		;ALL DONE
MORE50:	DPB	P1,BYTCNT	;SAVE BYTE COUNT
	MOVE	T3,.CPPC##	;JOB'S PC
	TLNN	T3,USRMOD	;IN USER MODE?
	POPJ	P,		;NO, TRY AGAIN LATER
	MOVE	T3,[EXP IC.UOU+TTYFLT##]
	MOVEM	T3,.CPPC##	;GO TO TTYFLT
	MOVEM	T1,.UPMP+.UPUPF	;STORE FAULT ADDRESS
	POPJ	P,


CKROOM:	MOVEI	T1,DEPAIO	;IF THIS JOB IS NOT USING
	TDNN	T1,DEVAIO(F)	; ASYNCHRONOUS I/O THEN
	JRST	CPOPJ1##	; JUST GIVE THE SKIP RETURN
	SKIPLE	T1,TTFREN##	;GET THE FREE CHUNK COUNT
	CAIG	T1,5		;ENOUGH ROOM?
	POPJ	P,0		;NO--QUIT NOW
	MOVE	T1,LDBTOC(U)	;GET OUTPUT BYTE COUNT
	ADDI	T1,↑D25		;REDUCE ODDS OF LOSSAGE
	CAMG	T1,TIWRNN	;TOO MUCH STUFF?
	AOS	(P)		;NO--CALL TYO
	POPJ	P,0		;RETURN
	SUBTTL	DDT MODE CALLI'S

;INPUT TO DDT	- CALL AC,[SIXBIT /DDTIN/]  WHERE AC/ ADDR
;ADDR GETS UP TO 21 WORDS OF ASCIZ, BREAKING ON ANY CHARACTER

DDTIN::	PUSHJ	P,SAVE3##	;SAVE P1-P3 (TYICC KRUMPS P3)
	PUSHJ	P,TTYFNU	;SET LINE AND DDB FOR THIS TTY
	PUSHJ	P,CKATTI	;MAKE SURE TERMINAL ATTACHED
	PUSHJ	P,GETWDU##	;DO ADDRESS CHECKING FIRST
	HRRZS	T1
	PUSHJ	P,IADRCK##	; ..
	  JRST	ADRERR##	;NO GOOD
	ADDI	T1,21		;CHECK END OF AREA
	PUSHJ	P,IADRCK##	; ..
	  JRST	ADRERR##	;NO GOOD
	MOVSI	P1,440700	;SEVEN BIT BYTES, RELOCATED.
	HRRI	P1,-21(T1)	;IN USER AREA
	MOVEI	P2,<21*5>-1	;NUMBER OF BYTES ALLOWED
	PUSHJ	P,TWAITC	;GET AT LEAST ONE CHARACTER
DDTINL:	SKIPG	LDBTIC(U)	;ANY MORE TO COME?
	JRST	DDTINX		;NO.
	PUSHJ	P,TYICC		;YES. GO GET ONE
	  JRST	DDTINX		;WASNT ANY. I'M CONFUSED.
	TRNE	T3,177		;NULL?
	EXCTUU	<IDPB T3,P1>	;NO. STORE IN USER AREA
	SOJG	P2,DDTINL	;IF MORE SPACE, GET ANOTHER CHARACTER
DDTINX:	MOVEI	T3,0		;FLAG END OF STRING
	EXCTUU	<IDPB T3,P1>	; IN USER AREA
	PJRST	NOCTRO		;AND RETURN TO USER, CLEARING ↑O FLAG

;DDTOUT - CALL AC,[SIXBIT /DDTOUT/], AC/ ADDR, ADDR/ ASCIZ /XXX/

DDTOUT::HRR	M,T1		;USER ADR. OF TEXT TO M
	PUSHJ	P,TTYFNU	;GET USER'S CONSOLE
	PUSHJ	P,CKATOU	;MAKE SURE AT USER LEVEL AND ATTACHED
	JRST	OUTSTR		;SAME AS THE CORRESPONDING TTCALL
	SUBTTL	TTCALL AND TRMOP. -- TTCALL DISPATCH

;TTCALL AC,E - VALUE OF AC DETERMINES ACTION OF UUO (051)

TTYUUO::PUSHJ	P,SAVE2##	;SAVE P1,P2
	PUSHJ	P,TTYFNU	;FIND CURRENT USER'S TTY
	MOVE	P2,TTUUOT(P1)	;GET PRE-CHECK BITS
	TLNE	P2,TC.ATW	;ATTACH OR WAIT?
	PUSHJ	P,CKATTO	;YES.  WAIT TILL ATTACHED
TTUUA:	TLNN	P2,TC.ATR	;ATTACH OR RETURN?
	JRST	TTUUB		;NO
	TRNN	U,-1		;YES.  LINE NON-ZERO?
	POPJ	P,0		;NO.  RETURN, NO TERMINAL

TTUUB:	JUMPE	U,TTUUD		;ONE UUO-GETLCH-CAN BE HERE DETACHED
	HLL	U,LDBDCH(U)	;GET LINE DESCRIPTION
	TLNN	P2,TC.USR	;USER OR RETURN?
	JRST	TTUUC		;NO
	TLNE	U,LDLCOM	;YES.  USER LEVEL?
	POPJ	P,0		;NO.  RETURN.

TTUUC:	TLNE	P2,TC.USW	;USER OR WAIT?
	TLNN	U,LDLCOM	;YES.  AT USER LEVEL
	JRST	TTUUD		;USER LEVEL, OR NOT NEEDED
	PUSHJ	P,CKATOU	;TOP LEVEL.WAIT FOR USER.
	JRST	TTYUUO		;RESTART UUO IN CASE OF
				;ATTACH.
TTUUD:	TLNN	P2,TC.ADC	;ADDRESS CHECK NEEDED?
	JRST	TTUUE		;NO.  GO DISPATCH.
	HRRZ	T1,M		;ADDRESS TO P1, WHICH IS P1
	PUSHJ	P,UADCK1##	;CHECK THE ADDRESS
TTUUE:	TLNE	P2,TC.ECS	;INPUT OPERATION?
	PUSHJ	P,TYIEAT	;YES, EAT COMMAND IF LEFT OVER
	JRST	@TTUUOT(P1)	;DISPATCH TO ROUTINE
;THE FOLLOWING TABLE IS USED TO PRE-CHECK AND DISPATCH THE TTCALL'S.
;BITS IN THE LEFT ARE CHECKED BEFORE DISPATCHING.
;INDIRECT AND INDEX MUST BE ZERO, FOR JRST INDIRECT, BUT THIS COULD
;EASILY BE CHANGED IF THE BITS RUN OUT.


TC.ADC==400000		;THIS FUNCTION MUST BE ADDRESS CHECKED
TC.USR==200000		;THIS FUNCTION MUST BE AT USER LEVEL, ELSE POPJ
TC.USW==100000		;THIS FUNCTION MUST BE AT USER LEVEL, ELSE WAIT
TC.ATW==040000		;THIS FUNCTION MUST BE ATTACHED, ELSE WAIT
TC.ATR==020000		;THIS FUNCTION MUST BE ATTACHED, ELSE POPJ
TC.ECS==010000		;EAT COMMAND SYNC (CALL TYIEAT)
;DON'T ASSIGN BITS 13-17 WITHOUT CHANGING DISPATCH CODE

TTUUOT:	XWD	TC.ATW+TC.USW+TC.ADC+TC.ECS,INCHRW	;(00) INPUT CHARACTER, WAIT
	XWD	TC.ATW+TC.USW,ONEOUT		;(01) OUTPUT CHARACTER
	XWD	TC.ATR+TC.USR+TC.ADC+TC.ECS,INCHRS	;(02) INPUT CHARACTER, SKIP
	XWD	TC.ATW+TC.USW,OUTSTR		;(03) OUTPUT AN ASCIZ STRING
	XWD	TC.ATW+TC.USW+TC.ADC+TC.ECS,INCHWL	;(04) INPUT CHARACTER, WAIT LINE MODE
	XWD	TC.ATR+TC.USR+TC.ADC+TC.ECS,INCHSL	;(05) INPUT CHARACTER, SKIP LINE MODE
	XWD	TC.ADC,GETLIN			;(06) GET LINE CHARACTERISTICS
	XWD	TC.ATW+TC.ADC,SETLIN		;(07) SET LINE CHARACTERISTICS
	XWD	TC.ATR,TRESCU			;(10) RESCAN COMMAND LINE
	XWD	TC.ATR,TSETBI			;(11) CLEAR INPUT BUFFER
	XWD	TC.ATR,TSETBO			;(12) CLEAR OUTPUT BUFFER
	XWD	TC.ATR+TC.USR+TC.ECS,SKPINC	;(13) SKIP IF A CHAR TO BE INPUT
	XWD	TC.ATR+TC.USR+TC.ECS,SKPINL	;(14) SKIP IF A LINE TO BE INPUT
	XWD	TC.ATW+TC.USW,IONEOU		;(15) IMAGE ONE-CHARACTER OUTPUT
	XWD	0,CPOPJ##			;(16) NOT IMPLEMENTED
	XWD	0,CPOPJ##			;(17) NOT IMPLEMENTED
	SUBTTL	TTCALL AND TRMOP. -- OUTCHR AND IMAGE OUTCHR

;ONEOUT OUTPUTS ONE CHARACTER FROM C(E)

ONEOUT:	PUSHJ	P,SAVE2##	;SAVE P2
	SKIPN	F		;ANY DDB?
	SKIPA	P2,[CCTYO]	;NO--MUST BE SLOPPY
	MOVEI	P2,TYO7W	;YES--BE NEAT
IFN FTRSP,<PUSHJ P,RSPTOR##>	;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
ONEOU1:	PUSHJ	P,GETWDU##	;PICK UP USER'S WORD
	MOVE	T3,T1		;PUT IN RIGHT AC
	ANDI	T3,177		;MASK OUT ANY JUNK
	JUMPE	T3,CPOPJ##	;IF NOT NULL,
	PJRST	(P2)		;TYPE OUT, WITH PARITY, WAIT IF NEEDED

;IONEOU OUTPUTS ONE CHARACTER FROM LOW 8 BITS OF C(E)
IONEOU:
IFN FTRSP,<PUSHJ P,RSPTOR##>	;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
	PUSHJ	P,CLRIIQ	;NOT IN INPUT WAIT ANY MORE
	JUMPE	F,ONEOU1	;IF NO DDB, SEND 7 BITS
	PUSHJ	P,GETWDU##	;GET USER'S DATUM
	HRRZ	T3,T1		;INTO RIGHT AC
	TRO	T3,400		;FLAG AS IMAGE CHARACTER (NO FILLER)
	PJRST	TYO9W		;SEND IMAGE CHARACTER (WAIT IF NEEDED)
	SUBTTL	TTCALL AND TRMOP. -- OUTSTR AND RESCAN

;OUTSTR OUTPUTS A STRING OF ASCIZ CHARACTERS

OUTSTR:
IFN FTRSP,<PUSHJ P,RSPTOR##>	;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
	PUSHJ	P,SAVE4##	;SAVE P1-P4
	MOVEI	P3,TYO7W
OUTST3:	LDB	T1,[POINT 9,M,26] ;PAGE #
	PUSHJ	P,TPSHS##	;IS PAGE SHARED?
	  JRST	OUTST6		;YES -- JUST USE
	HRROI	T1,(M)		;LEFT JUSTIFIED ASCIZ STRING
	PUSHJ	P,CKSTR##	;MAKE SURE ITS IN CORE AND LEGAL
	  JRST	UADERR##	;ADDRESS CHECK
OUTST6:	HRRI	M,-1(M)		;COMPENSATE FOR GETWD1
OUTST5:	MOVEI	P4,200		;MAXIMUM # OF WORDS IN ONE SHOT
OUTST2:	MOVE	P1,[POINT 7,P2]	;PREPARE TO READ BYTES
	PUSHJ	P,GETWD1##	;GET A USER'S WORD
	MOVE	P2,T1		;PUT WORD IN A SAFE AC
OUTST1:	TLNN	P1,760000	;ANY BYTES LEFT?
	JRST	OUTST4		;NO. GET ANOTHER WORD
	ILDB	T3,P1		;YES. GET ONE
	JUMPE	T3,CPOPJ##	;NULL MARKS END OF STRING
	PUSHJ	P,(P3)		;TYPE OUT CHARACTER WITH PARITY
	JRST	OUTST1		;AND GO BACK FOR MORE.

OUTST4:	SOJG	P4,OUTST2	;GO BACK FOR MORE. IS MESSAGE LONG?
	PUSHJ	P,SCDCHK##	;GIVE THE REST OF THE WORLD A CHANCE
	JRST	OUTST5

;TRESCU IS RESCAN FUNCTION FOR PROGRAM TO READ COMMAND THAT STARTED IT

TRESCU:	MOVE	T2,LDBBY2(U)	;SAVE OLD BIT FOR TEST
	MOVEI	T1,L2RECS	;CLEAR BIT IN LINE DATA BLOCK WHICH
	ANDCAM	T1,LDBBY2(U)	; WOULD CAUSE COMMAND TO BE SKIPPED
	TDNN	T2,T1		;SEE IF ANYTHING THERE
	TRNN	M,1		;NO--SEE IF USER WANTS TO KNOW
	POPJ	P,0		;NO--JUST RETURN
	JRST	CPOPJ1##	;YES--GIVE SKIP RETURN
	SUBTTL	TTCALL AND TRMOP. -- SKPINL AND SKPINC

;SKIP IF A LINE MAY BE INPUT

SKPINL:	PUSHJ	P,TYIEAT	;MAKE SURE NOT FAKED BY COMMAND
	PUSHJ	P,NOCTRO	;CLEAR THE ↑O BIT
	PJRST	TTLCHK		;CHECK FOR LINE READY
				; AND RETURN SKIP/NON-SKIP

;SKIP IF A CHARACTER MAY BE INPUT

SKPINC:	PUSHJ	P,TYIEAT	;MAKE SURE NOT FAKED BY COMMAND
	SKIPG	LDBTIC(U)	;ANY WAITING TO INPUT
	SKIPLE	LDBECC(U)	; OR WAITING FOR ECHO?
	AOS	(P)		;SAY SOMETHING'S THERE
	PJRST	NOCTRO		;AND CLEAR CTRL/O



NOCTRO:	MOVEI	T1,LDROSU	;CLEAR OUTPUT SUPPRESS BIT
	ANDCAM	T1,LDBDCH(U)	; IN LINE DATA BLOCK
	POPJ	P,0		;AND RETURN

STCTRO:	MOVEI	T1,LDROSU	;THE OUTPUT SUPPRESS BIT
	IORM	T1,LDBDCH(U)	;SET OUTPUT SUPPRESSION
	DPB	T1,LDPSVC	;CLEAR OUT ANY SAVED CHARACTER
	PJRST	TSETBO		;CLEAR OUTPUT BUFFER
	SUBTTL	TTCALL AND TRMOP. -- GETLIN

;GETLIN RETURNS A WORD OF INFORMATION ABOUT A LINE.

GETLIN:	PUSHJ	P,GETWDU##
	JUMPL	T1,GETLN1	;DOES HE WANT HIS OWN LINE
				; IF YES USE CURRENT C(U)
	TRZ	T1,.UXTRM	;CLEAR IO INDEX BIT
	CAIL	T1,TTPLEN##	;NO. DOES HE WANT A LEGAL ONE?
	JRST	GETLNZ		;NO. RETURN A ZERO
	MOVE	U,LINTAB##(T1)	;GET THE RIGHT LDB ADDRESS
GETLN1:	JUMPE	U,GETLNZ	;IN CASE RUNNING DETACHED
	HRRZ	F,LDBDDB(U)	;GET ATTACHED DDB
	SETZM	S		;ASSUME DETACHED
	SKIPE	F		;IS JOB DETACHED?
	MOVE	S,DEVIOS(F)	;GET STATUS BITS FOR TTY
	HLL	U,LDBDCH(U)	;GET DEVICE BITS FOR BELOW
	LDB	T1,LDPLNO	;GET THE LINE NUMBER FROM LDB
	TRO	T1,.UXTRM	;SET IO INDEX BIT
	HRL	T1,LDBDCH(U)	;GET RIGHT-HALF BITS.
	TLZ	T1,GTLMSK	;CLEAR BITS THAT ARE JUNK OR
				; THAT WILL BE SET BELOW
	LDB	T3,GETLP1	;GET BITS FROM LEFT OF LDBDCH
	DPB	T3,GETLP2	;AND PUT AT RIGHT PLACE IN T1
	TLC	T1,GTLT37	;THIS BIT IS WRONG SENSE
	TLNE	U,LDLCOM	;IS LINE AT COMMAND LEVEL?
	JRST	GETLN4		;YES.  SEE IF SHOULD BE CONSIDERED FOR INPUT
GETLN3:	MOVE	T3,T1		;SAVE AWAY BITS SO FAR
	PUSHJ	P,TTLCK2	;SEE IF ANY LINE READY
	  TDZA	T1,T1		;NO. CLEAR T1
	MOVSI	T1,GTLRDY	;YES. SET BIT
	IOR	T1,T3		;PUT NEW BIT WITH OLD BIT

GETLN5:	MOVEI	T3,L2RXON	;PAPER TAPE BIT
	TDNE	T3,LDBBY2(U)	;TEST IT
	TLO	T1,GTLXON	;YES. FLAG THAT
GETLN2:	PJRST	PUTWDU##	;GIVE RESULT TO USER
				;AND RETURN

GETLNZ:	MOVEI	T1,0		;RETURN ZERO FOR BAD LINE
	JRST	GETLN2		;GO RETURN THAT
GETLN4:	HRRZ	T3,LDBDDB(U)	;GET LINKED DDB, IF ANY
	JUMPE	T3,GETLN3	;IF NONE, CHECK COUNTS
	MOVE	T3,DEVMOD(T3)	;GET DEVICE MODE BITS
	TLNN	T3,TTYATC	;IS TTY ATTACHED CONSOLE?
	JRST	GETLN3		;NO.  CHECK COUNTS
	JRST	GETLN5		;YES.  IGNORE COUNTS WHILE AT COMMAND LEVEL

GETLP1:	POINT	4,LDBDCH(U),15	;TO GET SOME BITS FROM LDB
GETLP2:	POINT	4,T1,15		;TO COPY THEM TO T1
	SUBTTL	TTCALL AND TRMOP. -- SETLIN, INCHSL, INCHWL, INCHRS & INCHRW

;ROUTINE TO SET LINE CHARACTERISTICS WHICH ARE LEGAL FOR USER TO DIDDLE

SETLIN:	PUSHJ	P,GETWDU##
	HLRZS	T1		;SEE WHAT HE WANTS TO SET THEM TO
	TRC	T1,GTLT37	;STORED AS COMPLEMENT
	ROT	T1,-2		;THIS IS BIT-DEPENDENT, MATCHING POINTER
	DPB	T1,SETLP1	;THESE THREE BITS CAN BE SET
	MOVEI	T3,L2RXON	;AND THIS ONE (NON-ADJACENT)
	SKIPGE	T1		;HE WANT IT ON?
	IORM	T3,LDBBY2(U)	;YES.
	SKIPL	T1		;OR OFF?
	ANDCAM	T3,LDBBY2(U)	;OFF.
	PJRST	SETCHP		;TELL FE'S AND RETURN

SETLP1:	POINT	3,LDBDCH(U),15	;PART OF LEGAL BITS

INCHRS:	PUSHJ	P,SKPINC	;CAN I GET A CHARACTER (CLEAR ↑O)
	  POPJ	P,0		;NO. GIVE NON-SKIP RETURN
	PUSHJ	P,TWAITC	;WAIT IN CASE NOT ECHOED YET
ICS3:	PUSHJ	P,TYIS		;GET A CHARACTER
	  JRST	NOCTRO		;NONE THERE.
	AOS	0(P)		;GIVE SKIP RETURN
	JRST	ICW1		;AND RETURN THE CHARACTER

INCHSL:	PUSHJ	P,SKPINL	;IS THERE A LINE AVAILABLE?
	  POPJ P,0		;NO. NON-SKIP RETURN TO USER
	PUSHJ	P,TWAITL
	JRST	ICS3		;YES. GO GET A CHARACTER FOR HIM

INCHWL:	PUSHJ	P,TWAITL	;WAIT FOR A LINE TO APPEAR
	PUSHJ	P,TYI		;GO GET A CHARACTER
	  MOVEI	T3,0		;IMPOSSIBLE. NO CHARACTERS. USER SET IODERR?
ICW1:	ANDI	T3,177		;MASK TO SEVEN BITS
	MOVE	T1,T3
	PUSHJ	P,PUTWDU##	;GIVE HIM THE CHARACTER
	JRST	NOCTRO		;AND NON-SKIP RETURN

INCHRW:	PUSHJ	P,TWAITC	;WAIT FOR A CHARACTER TO APPEAR
	PUSHJ	P,TYI		;GO GET THE CHARACTER
	  MOVEI	T3,0		;IMPOSSIBLE. NONE THERE. USER SET IODERR?
	JRST	ICW1		;GIVE HIM T3 AND RETURN
	SUBTTL	TTCALL AND TRMOP. -- TRMNO. UUO

;TRMNO.	CALLI, TO GET TERMINAL NUMBER
;FOR SPECIFIED JOB NUMBER.
;	MOVE	AC,JOBNUMBER
;CALL	CALLI	AC,115
;	.ERROR RETURN
;	NORMAL RETURN		;AC HAS .UXTRM+LINE#

TRMNO::	CAMN	T1,[-1]		;IS ARG -1?
	MOVEI	T1,(J)		;YES, USE THIS JOB
	JUMPLE	T1,RTZER##	;ERROR IF JOB # 0 OR LESS THAN -1
	CAMLE	T1,HIGHJB##	; OR TOO BIG
	JRST	RTZER##		;..
	HRRZ	T1,TTYTAB##(T1)	;GET DDB ADDRESS
	JUMPE	T1,RTZER##	;ERROR IF NONE
	HRRZ	U,DDBLDB(T1)	;GET LDB ADDRESS
	JUMPE	U,RTZER##	;ERROR IF DETACHED
	LDB	T1,LDPLNO	;GET LINE NUMBER
	ADDI	T1,.UXTRM	;CONVERT TO UNIVERSAL
	JRST	STOTC1##	;SKIP RETURN INDEX TO USER
	SUBTTL	TTCALL AND TRMOP. -- TRMOP. DISPATCH

;TRMOP. UUO, OR CALLI 116.
;UUO TO PERFORM MISCELLANEOUS FUNCTIONS FOR
;A SPECIFIED TERMINAL.
;
;CALL:	MOVE	AC,[XWD N,ADR]
;	CALLI	AC,116
;	  ERROR	RETURN
;	NORMAL	RETURN
;

TRMOP::	PUSHJ	P,SAVE4##	;SAVE THE PRESERVED AC'S
	MOVE	P4,T1		;USER'S ARGUMENT TO P4
	HRRM	T1,M		;ADDRESS OF ARGUMENT LIST
	HLRZ	T2,T1		;CHECK FOR LENGTH AT LEAST 2
	CAIL	T2,2
	PUSHJ	P,GETWRD##	;GET USER'S ARG AT M
	  JRST	TOPX3		;ERROR CODE 3, ILLEGAL ADDRESS
	TLNE	T1,-1		;IF BITS IN L.H.
	JRST	RTZER##		; THEN BAD FUNCTION
	HRRZ	P1,T1		;COPY USER ARGUMENT
	JUMPLE	P1,RTZER##	;ZERO ERROR IF BAD ARGUMENT CODE
	PUSHJ	P,GETWR1##	;GET IT, IF POSSIBLE
	  JRST	TOPX3		;NOT A LEGAL ADDRESS
	SUBI	T1,.UXTRM	;REMOVE TERMINAL OFFSET
	CAME	T1,[-1-.UXTRM]	;WANTS CONTROLLING TTY?
	JRST	TRMNRM		;NO
	HRRZ	T1,TTYTAB##(J)	;YES, GET DDB ADDRESS
	JUMPE	T1,RTZER##	;ERROR IF NONE
	HRRZ	U,DDBLDB(T1)	;GET LDB ADDRESS
	JUMPE	U,RTZER##	;DETACHED
	LDB	T1,LDPLNO	;GET LINE NUMBER
TRMNRM:	JUMPL	T1,RTZER##	;RANGE CHECK THE TERMINAL #
	CAIL	T1,TTPLEN##	;..
	  JRST	RTZER##		;BAD LINE NUMBER
	HRRZ	U,LINTAB##(T1)	;OK. GET THE LDB ADDRESS
	HRRZ	F,LDBDDB(U)	;AND DDB, IF ANY.
	JUMPN	F,TRMO1		;DID WE FIND M DDB?
	HRLZ	T2,LDBDCH(U)	;NO, GET LINE STATUS
	JUMPGE	T2,TRMO1	;PTY?
	SUBI	T1,TCONLN##+1	;YES, GET NUMBER
	HRRZ	F,PTYTAB(T1)	;GET DDB ADDR


;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

TRMO1:	MOVE	T1,P1		;GET USER'S FUNCTION CODE
	TRNE	T1,3000		;READ/SET CODE?
	JRST	TOPRSQ		;PROBABLY. GO SEE.
	CAILE	T1,TOPLN0	;IS IT AN ACTION CODE?
	JRST	RTZER##		;NO. NO SUCH CODE
	HRRI	M,1(M)		;ADVANCE M
	MOVE	P3,TOPTB0-1(T1)	;PICK UP DISPATCH WORD
IFN FTMIC,<
	MOVSI	P2,(JB.LSY)	;PROGRAM FROM SYS BIT
	TLNE	P3,(TOP.MC)	;MIC TRMOP?
	TDNN	P2,JBTLIM##(J)	;AND DID THIS PROGRAM COME FROM SYS?
	JRST	CHKRED		;NO TO EITHER
	MOVSI	P2,'MIC'	;RUNNING MIC?
	CAMN	P2,JBTNAM##(J)	;SKIP IF NO
	JRST	CHKDDB		;RUNNING MIC, NO FUTHER CHECKING REQUIRED
CHKRED:	MOVSI	T1,JP.POK
	TLNE	P3,(TOP.MR)
	PUSHJ	P,PRVBIT
	  SKIPA
	JRST	TOPX1
>
	TLNN	P3,(TOP.RP)	;DO WE NEED READ PRIVS?
	JRST	CHKWRT		;NO--SEE IF WE NEED WRITE PRIVS
	PUSHJ	P,TREDOK	;YES--DO WE HAVE READ PRIVS?
	  JRST	TOPX1		;NO--GIVE ERROR RETURN
CHKWRT:	TLNN	P3,(TOP.WP)	;DO WE NEED WRITE PRIVS?
	JRST	CHKDDB		;NO--DISPATCH
	PUSHJ	P,TWRTOK	;YES--DO WE HAVE READ PRIVS?
	  JRST	TOPX1		;NO--GIVE ERROR RETURN
CHKDDB:	TLNN	P3,(TOP.NF)	;NEED F?
	JRST	(P3)		;NO--ALLSET
	PUSHJ	P,TOPDDB	;YES--GET DDB
	  JRST	TOPX6		;CAN'T GIVE ERROR
	JRST	(P3)		;YES--DO THE TRMOP.
;HERE IF REQUESTED FUNCTION NOT FROM 1 THRU TOPLN0-1
;F AND U ARE SET UP TO THE DESIRED LINE.

TOPRSQ:	ANDI	P1,777		;JUST THE ITEM NUMBER
	TRZE	T1,1000		;READ CODE?
	JRST	TOPRED		;PROBABLY
	CAIL	T1,2000+TOPLN1	;NO. SET CODE?
	JRST	RTZER##		;NOT A LEGAL CODE
TOPSET:	HLRZ	T2,P4		;IS THERE ANOTHER DATUM?
	CAIGE	T2,3		;..
	JRST	TOPX3		;NO. CAN'T DO THE SET.
	HRRI	M,1(M)		;YES. GO GET IT
	PUSHJ	P,GETWRD##	;..
	  JRST	TOPX3		;NOT A LEGAL ADDRESS
	MOVE	P2,T1		;SAVE ARGUMENT
	PUSHJ	P,TWRTOK	;DOES HE HAVE WRITE PRIVS?
	  JRST	TOPX1		;NO. ERROR CODE 1.
TOPST1:	LDB	T1,TOPSYR	;LEGAL TO TRY SETTING.
	JUMPE	T1,TOPST2	;RANGE CHECK REQUIRED?
	HLRZ	T2,TOPSRT-1(T1)	;YES. GET MINIMUM VALUE
	CAMGE	P2,T2		;SUPPLIED .GE. MINIMUM?
	JRST	TOPX2		;NO. BAD ARG, TOO SMALL
	HRRZ	T2,TOPSRT-1(T1)	;OK. CHECK MAXIMUM
	CAMLE	P2,T2		;..
	JRST	TOPX2		;BAD. ARG TOO BIG.
TOPST2:	SKIPN	T2,TOPTB1(P1)	;SET ALLOWED?
	PJRST	RTZER##		;ILLEGAL/UNKNOWN FUNCTION
TOPST3:	TLNE	T2,(TOP.SA)	;OK TO SET?
	JRST	TOPST4		;YES--DO SO
	TLNN	T2,(TOP.PS)	;NEED PRIVS?
	JRST	TOPX1		;NO--CAN NOT SET
	MOVSI	T1,JP.POK	;POKE BIT
	PUSHJ	P,PRVBIT##	;IS IT SET?
	  JRST	TOPST4		;YES--DO SET
	JRST	TOPX1		;NO. NOT ALLOWED.
TOPST4:	TLNN	T2,(TOP.IF)	;THIS FUNCTION ILLEGAL FOR FRCLIN?
	JRST	TOPST5		;NO, CONTINUE
	LDB	T1,LDPLNO	;GET LINE NUMBER
	CAIN	T1,FRCLIN##	;IS IT FRCLIN?
	JRST	TOPX1		;YES, ILLEGAL
TOPST5:	TLNE	T2,(TOP.RT)	;NEED A ROUTINE TO SET?
	PJRST	1(T2)		;YES, SET ROUTINE IS ADDRESS+1
	LDB	T1,0(T2)	;FETCH WHAT THE STATE IS CURRENTLY
	CAMN	T1,P2		;WILL IT CHANGE?
	JRST	CPOPJ1		;NO, DON'T SEND STATUS CHANGE THEN
	MOVEI	T1,LDRPTY	;THE LINE-IS-A-PTY BIT
	CAIN	P1,4		;SET SLAVE?
	TDNN	T1,LDBDCH(U)	; ON PTY?
	DPB	P2,0(T2)	;OK. CHANGE ITEM.
IFN FTD10H,<
	CAIN	P1,27		;ARE WE SETTING APL?
	DPB	P2,[POINT 1,LDBBCD(U),11] ;YES, SET IT WHERE DLSINT
				; LOOKS FOR IT
>
IFN FTCAFE,<
TOPTFE:	MOVSI	T1,(TOP.PE)	;DO WE NEED TO CHANGE
	TDNN	T1,TOPTB1(P1)	; HARDWARE PARAMS FOR THIS LINE
	JRST	CPOPJ1##	;NO--JUST RETURN
	PUSHJ	P,SETCHP
> ;END FTCAFE
	JRST	CPOPJ1##	;SKIP RETURN
TOPRED:	CAIL	T1,TOPLN1	;LEGAL ITEM NUMBER?
	JRST	RTZER##		;NO. ERROR RETURN
	PUSHJ	P,TREDOK	;OK TO DO A READ?
	  JRST	TOPX1		;NO. PROTECTION FAILURE.
	SKIPN	T1,TOPTB1(P1)	;OK. GET TABLE ENTRY.
	JRST	RTZER##		;ILLEGAL/UNKNOWN FUNCTION
	TLNE	T1,(TOP.RT)	;NEED A ROUTINE
	JRST	TOPRD1		;YES, GO DISPATCH
	LDB	T1,0(T1)	;GET BYTE POINTED TO
	PJRST	STOTC1##	;AND RETURN IT TO USER

TOPRD1:	PUSHJ	P,0(T1)		;ZERO OFFSET TO READ
	PJRST	STOTC1		;RETURN RESULT TO USER AND SKIP RETURN


;ROUTINE TO HANDLE FUNCTION 1000

TOPOIP:
; mco ScnSer-32 for spr 31716 by provan on march 5, 1982
;[9747]	SETZ	T1,		;ASSUME LINE IS IDLE
;[9747]	SKIPL	LDBDCH(U)	;IDLE
	pushj	p,topsop	;[ScnSer-32] skip return if more to output
	 tdza	t1,t1		;[ScnSer-32] clear busy flag, output done
	  MOVEI	T1,1		;SET BUSY FLAG
	POPJ	P,		;...

;ROUTINE TO FETCH/SET THE VALUE OF HPOS

TOPHPS:	JRST	TOPHPR		;HERE FOR READ
	LDB	T2,LDPWID	;HERE FOR SET.  GET CARRIAGE WIDTH
	MOVNS	T2		;MINUS
	ADD	T2,P2		;PLUS USERS ARGUMENT
	MOVEM	T2,LDBHPS(U)	;SETUP IN LDB
	JRST	CPOPJ1##	;AND SIGNAL GOOD RETURN

TOPHPR:	PUSHJ	P,HPOS		;GET POSITION
	MOVE	T1,T2		;GET INTO CORRECT AC
	POPJ	P,
;ROUTINE TO HANDLE FUNCTION 1041

TOPTTC:	JRST	TOPTT1		;GET TERMINAL TYPE
	MOVE	T2,P2		;GET USER'S ARGUMENT
	PUSHJ	P,TTUTYP##	;SET TERMINAL CHARACTERISTICS
	  JRST	TOPX2		;UNKNOWN TERMINAL TYPE
	JRST	CPOPJ1##	;GOOD RETURN

TOPTT1:	LDB	T1,LDPTTT	;GET TERMINAL TYPE
	TRZE	T1,100		;CUSTOMER DEFINED TERMINAL TYPE ?
	MOVNS	T1		;YES
	MOVE	T1,TTTWDT##(T1)	;GET TERMINAL NAME
	POPJ	P,		;STORE ANSWER FOR THE USER AND RETURN



;ROUTINE TO HANDLE FUNCTION 1045 (READ/SET ↑O STATE)

TOPSUP:	JRST	TOPSU5		;READ AND RETURN
	TRNE	P2,1		;SET OR CLEAR ↑O?
	JRST	TOPSU2		;SET IT
	PUSHJ	P,NOCTRO	;CLEAR IT
	JRST	CPOPJ1##	;RETURN HAPPILY

TOPSU2:	PUSHJ	P,STCTRO	;SET ↑O STATE
	JRST	CPOPJ1##	;RETURN SUCCESSFULLY

TOPSU5:	LDB	T1,LDPOSU	;GET ↑O BIT
	POPJ	P,		;AND RETURN IT TO USER



;ROUTINE TO RETURN TOTAL INPUT CHARACTER COUNT

TOPCCT:	MOVE	T1,LDBTIC(U)	;INPUT CHARACTER COUNT AVAILABLE TO USER
	ADD	T1,LDBECC(U)	;PLUS THOSE NOT YET ECHOED
	POPJ	P,		;RETURN TOTAL MONITOR CHARACTER COUNT
;SUBROUTINE TO CHECK FOR READ PRIVS
;CALL WITH:
;	F = DDB OF TARGET OR 0
;	PUSHJ	P,TREDOK
;	  RETURN HERE IF ERROR
;	RETURN HERE IF OK TO READ

TREDOK:	PUSHJ	P,SAVE3##	;SAVE P1,P2 AND P3
	MOVSI	P1,PVSPYM	;LOAD UP THE SPY BIT
	JRST	MYTTY		;JUMP TO COMMON CODE

;SUBROUTINE TO CHECK FOR WRITE PRIVS
;CALL WITH:
;	F = DDB OF TARGET OR 0
;	PUSHJ	P,TWRTOK
;	  RETURN HERE IF ERROR
;	RETURN HERE IF OK
;PRESERVES ALL AC'S

TWRTOK:	PUSHJ	P,SAVE3##	;SAVE P1,P2 AND P3
	MOVSI	P1,JP.POK	;FALL INTO COMMON CODE
MYTTY:	SKIPE	P2,F		;IS THERE A DDB?
	LDB	P2,PJOBN##	;YES--GET THE OWNERS JOB NUMBER
	CAMN	P2,J		;DO I OWN THIS TERMINAL
	JRST	MYTTY1		;CHECK PRIVS FOR MIC STYLE TRMOP
MYTTY2:	EXCH	P1,T1		;SAVE T1 AND SET UP PRIV BIT
	PUSHJ	P,PRVBIT##	;CHECK THE BIT
	  AOS	(P)		;OK TO READ OR SET
	MOVE	T1,P1		;RESTORE T1
	POPJ	P,0		;RETURN

MYTTY1:	
IFE FTMIC,<JRST CPOPJ1##>	;OK TO DO YOUR THING
IFN FTMIC,<
	TLNN	P3,(TOP.MC)	;MIC TRMOP?
	JRST	CPOPJ1##	;NO--OK TO DO YOUR THING
	MOVE	P2,DEVMOD(F)	;IS THE TARGET TTY...
	TLNE	P2,TTYATC	;CONTROLLING HIS JOB?
	JRST	CPOPJ1##	;YES--OK TO DO MIC TRMOP
	MOVE	P2,LDBDCH(U)	;NO--IS THE TARGET TTY...
	TRNE	P2,LDRCTY	;A CTY?
	JRST	MYTTY2		;YES--CHECK PRIVS
	CAMN	U,OPRLDB##	;IS THIS "OPR"?
	JRST	MYTTY2		;YES--CHECK PRIVS
	HRRZ	P3,TTYTAB##(J)	;GET USER'S TTY DDB ADDRESS
	JUMPE	P3,MYTTY2	;ERROR IF NONE
	HRRZ	P3,DDBLDB(P3)	;USER'S LDB ADDRESS
	JUMPE	P3,MYTTY2	;DETACHED
	MOVE	P3,LDBDCH(P3)	;USER'S TTY CHARACTERISTICS BITS
	TRNN	P3,LDRDSR	;IS HE A LOCAL TTY?
	JRST	CPOPJ1##	;YES--LET HIM DO MIC TRMOP TO EITHER REMOTE OR LOCAL TTY'S
	TRNE	P2,LDRDSR	;NO--TARGET TTY ANOTHER REMOTE TTY?
	JRST	CPOPJ1##	;YES--DO IT
	JRST	MYTTY2		;NO--CHECK PRIVS
>
;ERROR RETURNS

ERCODE	TOPX1,TRMNP%		;(1) ERROR CODE FOR PROT CHECK
ERCODE	TOPX2,TRMBR%		;(2) ERROR CODE FOR RANGE BAD
ERCODE	TOPX3,TRMIA%		;(3) ERROR CODE FOR ADDRESS BAD.
ERCODE	TOPX4,TRMCD%		;(4) ERROR CODE FOR NOT POSSIBLE TO DO
ERCODE	TOPX5,TRMDO%		;(5) ERROR IN DIALLER OPERATION
ERCODE	TOPX6,TRMND%		;(6) CAN NOT GET DDB
;TOPTB0 - TRMOP. ACTION FUNCTIONS LESS THAN 1000 

	TOP.RP==1B1		;NEED READ PRIVS TO DO THIS FUNCTION
	TOP.WP==1B2		;NEED WRITE PRIVS TO DO THIS FUNCTION
	TOP.NF==1B3		;NEED F SETUP TO DO THIS FUNCTION
IFN FTMIC,<
	TOP.MC==1B4		;THIS FUNCTION IS LEGAL IF RUNNING MIC
	TOP.MR==1B5		;FUNCTION REQUIRES MIC
>

IF2,<
IFNDEF	TOPABR,<TOPABR==RTZER##>
IFNDEF	TOPELE,<TOPELE==RTZER##>
> ;END IF2 CONDITIONAL

TOPTB0:	EXP	TOP.RP+TOPSIP			;1 - SKIP IF INPUT PRESENT
	EXP	TOP.RP+TOPSOP			;2 - SKIP IF OUTPUT PRESENT
	EXP	TOP.WP+TOPCIB			;3 - CLEAR INPUT BUFFER
	EXP	TOP.WP+TOPCOB			;4 - CLEAR OUTPUT BUFFER
	EXP	TOP.RP+TOP.WP+TOPOUC		;5 - OUTPUT CHAR
	EXP	TOP.RP+TOP.WP+TOP.NF+TOPOIC	;6 - OUTPUT IMAGE CHAR
	EXP	TOP.RP+TOP.WP+TOPOUS		;7 - OUTPUT STRING
	EXP	TOP.RP+TOP.WP+TOPINC		;10 - INPUT CHAR
	EXP	TOP.RP+TOP.WP+TOPIIC		;11 - INPUT IMAGE CHAR
	EXP	TOP.WP+TOPDSE			;12 - DATASET ENABLE
	EXP	TOP.WP+TOPDSC			;13 - DATASET CALL
	EXP	TOP.WP+TOPDSF			;14 - DATASET OFF
	EXP	TOP.RP+TOP.WP+TOPRES		;15 - RESCAN
	EXP	TOP.WP+TOPELE			;16 - SET TYPE ELEMENT
	EXP	TOP.WP+TOPABR			;17 - ENABLE AUTO BAUD DETECT
	EXP	TOP.RP+TOP.WP+TOPISC		;20 - INPUT CHAR.
	EXP	TOP.RP+TOP.WP+IFN FTMIC,<TOP.MC>+TOPMTY	;21 - MICTYP
IFN FTMIC,<
	EXP	TOP.RP+TOP.WP+TOP.MC+TOPMGT	;22 - MICGET
	EXP	TOP.RP+TOP.WP+TOP.MC+TOP.MR+TOPMST;23 - MICSET
	EXP	TOP.RP+TOP.WP+TOP.MC+TOPMCL	;24 - MICCLR
>
IFE FTMIC,<
	EXP	RTZER##				;22 - NOT IMPLEMENTED
	EXP	RTZER##				;23 - NOT IMPLEMENTED
	EXP	RTZER##				;24 - NOT IMPLEMENTED
>
	EXP	TOP.RP+TOP.WP+IFN FTMIC,<TOP.MC>+TOPMDP	;25 - MICDPY
IFN FTMIC,<
	EXP	TOP.RP+TOP.WP+TOP.MC+TOPMRS	;26 - MICDSP
IFN FTMLOG,<
	EXP	TOP.MC+TOP.RP+TOP.WP+TOPMLG	;27 - MICLOG
>
IFE FTMLOG,<
	EXP	RTZER##				;27 - NOT IMPLEMENTED
>
>
IFE FTMIC,<
	EXP	RTZER##				;26 - NOT IMPLEMEMTED
	EXP	RTZER##				;27 - NOT IMPLEMENTED
>
	EXP	TOPDSS				;30 - RETURN DATA SET STATUS
TOPLN0==.-TOPTB0
IFN FTPATT,<BLOCK 1>				;   - FOR PATCHING
;TOPTB1 - TRMOP. READ/SET FUNCTIONS GREATER THAN 1000
;CONTENTS OF TOPTB1 ARE AS FOLLOWS
;BITS 0-5 ARE RANGE TABLE INDEX FOR RANGE CHECK ON SET.
;BITS 6-12 ARE FLAGS FOR DETERMINING LEGALITY OF TRMOP UUO
;RH IS ADDRESS OF BYTE POINTER.

TOP.SA==1B6	;SET ALLOWED
TOP.PS==1B7	;SET ALLOWED FOR PRIVILEGED JOB ONLY
TOP.PE==1B8	;POKE THE FRONT END IF SET
TOP.RT==1B9	;FETCH/SET REQUIRES A ROUTINE.  ENTERED AT ADDRESS+0
		;FOR FETCH, ADDRESS+1 FOR SET.  FETCH ROUTINE MUST
		;RETURN VALUE IN T1.  SET ROUTINE'S RETURN IS PROPAGATED
		;BACK TO USER.
TOP.IF==1B10	;THIS FUNCTION IS ILLEGAL FOR FRCLIN NO MATTER IF
		;THE JOB IS PRIVILEGED OR NOT

;NOTE: THESE DEFINITIONS MUST AGREE WITH LDB DEFINITIONS
TOPTB1:	EXP	<0>B5+<TOP.RT>+<TOPOIP>					;1000
	EXP	<0>B5+<0>+<[POINT 1,LDBDCH(U),↑L<(LDLCOM)>]>		;1001
	EXP	<0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBBY2(U),↑L<L2RXON>]>;1002
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPLCT>			;1003
	EXP	<0>B5+<TOP.SA+TOP.IF>+<[POINT 1,LDBDCH(U),↑L<(LDLSLV)>]> ;1004
	EXP	<0>B5+<TOP.SA+TOP.PE>+<LDPTAB>				;1005
	EXP	<0>B5+<TOP.SA>+<LDPFRM>					;1006
	EXP	<0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBDCH(U),↑L<(LDLLCP)>]>;1007
	EXP	<0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBDCH(U),↑L<(LDLNFC)>]>;1010
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.RT>+<TOPHPS>			;1011
	EXP	<1>B5+<TOP.SA+TOP.PE>+<LDPWID>				;1012
	EXP	<0>B5+<TOP.SA>+<[POINT 1,LDBBY2(U),↑L<(L2LSND)>]>	;1013
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 1,LDBDCH(U),↑L<LDRHLF>]>	;1014
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 1,LDBDCH(U),↑L<LDRRMT>]>	;1015
	EXP	<0>B5+<TOP.SA>+<[POINT 1,LDBPAG(U),↑L<(LPLDIS)>]>	;1016
	EXP	<2>B5+<TOP.SA+TOP.PE>+<LDPFLC>				;1017
	EXP	<0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBBY2(U),↑L<(L2LTAP)>]>;1020
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<[POINT 1,LDBPAG(U),↑L<(LPLPAG)>]>;1021
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<[POINT 1,LDBDCH(U),↑L<(LDLSTP)>]>;1022
	EXP	<3>B5+<TOP.SA+TOP.IF>+<LDPPSZ>				;1023
	EXP	<3>B5+<LDPPCT>						;1024
	EXP	<0>B5+<TOP.SA>+<[POINT 1,LDBPAG(U),↑L<(LPLBLK)>]>	;1025
	EXP	<0>B5+<TOP.SA>+<LDPALT>					;1026
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPAPL>			;1027
	EXP	<4>B5+<TOP.SA+TOP.PE>+<LDPRSP>				;1030
	EXP	<4>B5+<TOP.SA+TOP.PE>+<LDPTSP>				;1031
	EXP	<0>B5+<TOP.SA+TOP.PE>+<LDPDBK>				;1032
	EXP	<0>B5+<TOP.PS+TOP.PE+TOP.IF>+<LDP274>			;1033
	EXP	<0>B5+<TOP.SA+TOP.PE>+<LDPTDY>				;1034
	EXP	<5>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPACR>			;1035
	EXP	TOP.SA+LDPRTC						;1036
	EXP	<0>B5+<TOP.SA>+<[POINT 36,LDBPBK(U),35]>		;1037
	EXP	<0>B5+<TOP.SA+TOP.PE>+<LDPDEM>				;1040
	EXP	<0>B5+<TOP.SA+TOP.RT+TOP.IF>+<TOPTTC>			;1041
IFN FTRSP!FTACCT,<
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 36,LDBBCT(U),35]>		;1042
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 36,LDBICT(U),35]>		;1043
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 36,LDBOCT(U),35]>		;1044
> ;END IFN FTRSP!FTACCT
IFE FTRSP!FTACCT,<EXP 0,0,0>
	EXP	<0>B5+<TOP.SA+TOP.RT>+<TOPSUP>				;1045
	EXP	<0>B5+LDPFCS						;1046
	EXP	<0>B5+LDPBKA						;1047
	EXP	0							;1050
	EXP	0							;1051
	<0>B5+<[POINT 36,LDBTIC(U),35]>					;1052
	EXP	0							;1053
	<0>B5+<[POINT 36,LDBBKC(U),35]>					;1054
	<0>B5+<[POINT 36,LDBECC(U),35]>					;1055
	<0>B5+<TOP.RT>+<TOPCCT>						;1056
	<0>B5+<[POINT 36,LDBTOC(U),35]>					;1057
IFN FTPATT,<
	EXP	0		;FOR PATCHING
	EXP	0		;FOR PATCHING
>
TOPLN1==.-TOPTB1
TOPSYR:	POINT	6,TOPTB1(P1),5	;POINTER TO RANGE TABLE INDEX

;THIS IS THE RANGE TABLE
TOPSRT:	XWD	↑D16,↑D255	;(1)MIN AND MAX WIDTHS
	XWD	0,3		;(2)MIN AND MAX FILLER CLASSES
	XWD	0,↑D63		;(3)MIN AND MAX PAGE LENGTH
	XWD	0,17		;(4)MIN AND MAX SPEED
	XWD	0,↑D200		;(5)AUTO C.R. TABLE
IFN FTPATT,<BLOCK 1>	;FOR PATCHING
	SUBTTL	TTCALL AND TRMOP. -- SKIPS AND CLEARS

TOPSIP==SKPINC

; mco 9747 and ScnSer-32 for spr 31716 by provan on march 5, 1982
TOPSOP::	;[9747] make global routine
;[9747]	SKIPG	LDBTOC(U)	;OUTPUT READY?
;[9747]	SKIPL	LDBDCH(U)	;OR OUTPUT IN PROGRESS?
	movsi	t2,lplpok	;[9747] the tty queued-by-topoke bit
	tdnn	t2,ldbpag(u)	;[9747] is the terminal queued for service?
	 skipl	t2,ldbdch(u)	;[9747] no, is service currently active?
		.cref	ldlidl	;[9747]  (cref reference to symbolic name)
	  jrst	cpopj1##	;[9747] output active or terminal queued
	skiple	ldbtoc(u)	;[ScnSer-32] more characters to output
	  jrst	cpopj1##	;[ScnSer-32] yes, skip return
	move	t2,ldbbyt(u)	;[9747] get defer bits
	trne	t2,l1rdem	;[9747] uf defered echo
	 trne	t2,l1rdec!l1rdel ;[9747] only if wants input
	 skipn	ldbecc(u)	;[ScnSer-32] anything to echo
	 skipe	ldbflp(u)	;[ScnSer-32] or output from fillers
	  AOS	0(P)		;YES. SKIP RETURN
	POPJ	P,0		;RETURN
TOPCIB:	AOS	0(P)		;SUCCESS RETURN
	PJRST	TSETBI		;CLEAR INPUT BUFFER
TOPCOB:	AOS	0(P)		;SUCCESS RETURN
	PJRST	TSETBO		;CLEAR OUTPUT BUFFER

;FOLLOWING NOT DONE YET
	TOPIIC==RTZER##

IFE FTMODM,<
	TOPDSE==CPOPJ##
	TOPDSF==CPOPJ##
	TOPDSC==CPOPJ##
	TOPDSS==CPOPJ##
>
	SUBTTL	TTCALL AND TRMOP. -- TRMOP. I/O

;OUTPUT 1 CHAR

TOPOUC:	AOS	(P)
	PUSHJ	P,TOPDDB	;GET A DDB
	  SETZM	F		;NO--DON'T NEED IT BADLY
	JRST	ONEOUT		;TYPE

;OUTPUT A STRING

TOPMDP:	MOVEI	T1,LDROSU	;CLEAR CONTROL O BIT
	ANDCAM	T1,LDBDCH(U)	;SO DATA WILL BE SEEN
	TDZA	F,F		;SO CCTYO WILL BE USED (AVOID TIOW)
TOPOUS:	SETOM	F		;SEARCH FOR A DDB
	AOS	(P)
	PUSHJ	P,GETWDU##	;GET POINTER
	HRRZ	M,T1		;PUT IN RIGHT AC
	JUMPE	F,TOPOU1	;USE CCTYO FOR MIC TYPEOUT
	PUSHJ	P,TOPDDB	;GET DDB
	  JRST	TOPOU1		;IF NO DDB
	HRRZ	T1,TTYTAB##(J)	;CONTROLLING TTY
	CAIN	T1,(F)		;IS THIS IT?
	PJRST	OUTSTR		;YES, THEN TOPOUS IS SAME AS OUTSTR
	PUSHJ	P,SAVE4##	;SET TO JOIN OUTSTR CODE IN MIDDLE
	MOVEI	P3,TYO7W	;TYPEOUT ROUTINE
	PJRST	OUTST3		;JOIN OUTSTR

TOPOU1:	PUSHJ	P,SAVE4##	;SET TO JOIN OUTSTR CODE IN MIDDLE
	MOVEI	P3,CCTYO
	PJRST	OUTST3		;JOIN OUTSTR

;OUTPUT IMAGE CHAR

TOPOIC::AOS	(P)		;SKIP RETURN			
	JRST	IONEOU		;TYPE IT
;INPUT A CHAR

TOPISC:	SKIPA	P1,[EXP INCHRW]
TOPINC:	MOVEI	P1,INCHWL
	AOS	(P)
	LDB	T1,PUUOAC##	;WHERE TO PUT ANSWER
	HRR	M,T1
	PUSHJ	P,TOPDDB
	  SETZB	F,S		;NO DDB, NO I/O STATUS
	PUSHJ	P,TYIEAT	;EAT ANY LEFT-OVER COMMAND
	PJUMPN	F,(P1)		;INPUT AND BLOCK IF A DDB AVAILABLE
	PUSHJ	P,TYI		;NO DDB, CAN'T BLOCK, GET CHAR
	  MOVEI	T3,0		;NONE THERE--RETURN NULL
	MOVE	T1,T3		;COPY CHAR
	JRST	STOTAC##	;STORE FOR USER

;INPUT IMAGE CHAR

TOPIIC==RTZER##

;DO A RESCAN

TOPRES:	PUSHJ	P,TRESCU	;DO IT
	  JRST	CPOPJ1##	;WIN
	JRST	CPOPJ1##	;WIN
	SUBTTL	TTCALL AND TRMOP. -- TRMOP. I/O SUBROUTINES

;GET A DDB FOR TRMOP. I/O

TOPDDB:	SETZ	S,		;IN CASE NO I/O STATUS AVAILABLE
	HRRZ	F,LDBDDB(U)	;GET DDB POINTER
	JUMPN	F,TOPDD2	;FIND A DDB?
	HRLZ	T2,LDBDCH(U)	;NO, GET THE LINE STATUS
	JUMPGE	T2,TOPDD2	;IS IT A PTY?
	LDB	T1,LDPLNO	;YES, GET THE TTY NUMBER
	HRRZ	F,PTYTAB##-PTYOFS##(T1)	;GET DDB ADDRESS, IF ANY
TOPDD2:	JUMPE	F,TOPDD1	;ANY DDB THERE?
	MOVE	S,DEVIOS(F)	;AH - A DDB, GET I/O STATUS
	LDB	T1,PJOBN##	;YES--IS IT MINE?
	CAMN	T1,.CPJOB##	; ..
	AOSA	(P)		;YES--USE IT
	SETZ	S,		;NO, THEN NO I/O STATUS AFTER ALL
	POPJ	P,		;RETURN AS APPROPRIATE

TOPDD1:	PUSHJ	P,TTYNAM	;GET SIXBIT NAME
	MOVE	T1,T2		;PUT IN T1
	PUSHJ	P,GETDDB	;GET A DDB
	  POPJ	P,		;NONE LEFT
	MOVEI	T1,ASSPRG	;INIT THE DDB SO
	IORM	T1,DEVMOD(F)	; IT WILL STICK
	MOVE	T1,.CPJOB##	; AROUND AND WE
	DPB	T1,PJOBN##	; CAN WAKE OWNER
	MOVE	S,DEVIOS(F)	;LOAD UP I/O STATUS WORD
	AOS	(P)		;SKIP RETURN (CALL?)
	PUSHJ	P,@0(P)		;CALL OUR CALLER
	  JRST	.+2		;NON-SKIP
	AOS	-1(P)		;SKIP
	PUSHJ	P,TTYREL	;KILL OFF DDB
	JRST	TPOPJ##		;AND RETURN
	SUBTTL	TTCALL AND TRMOP. -- TRMOP. DATASET FUNCTIONS

IFN FTMODM,<
;MORE SUBROUTINES FOR TRMOP

TOPDSE:	MOVE	T1,LDBDCH(U)	;GET DEVICE CHARACTERISTICS
IFN FTNET,<
	TRNE	T1,LDRREM	;REMOTE LINE
	JRST	[PUSHJ P,NETDSE	;LET NETSER DO IT
		 JRST CPOPJ1##]	;SKIP RETURN
>
	PUSHJ	P,CHKDSD	;(1)IS IT A DATASET?
	JRST	TOPX4		;NO. ERROR CODE 4
	LDB	U,LDPDSC	;GET THE TABLE OFFSET INTO U
	MOVSI	T1,DSCIC2	;CLEAR FAILURE, DIALLER FLAGS AND TIMER
	ANDCAM	T1,DSCTAB##(U)	; ..
	MOVSI	T1,DSCSWC	;SET TO ALLOW HIM ON
	PUSHJ	P,DSRRN1	;SEND TO MODEM HANDLER
	JRST	CPOPJ1##	;AND SKIP RETURN

TOPDSF:	MOVE	T1,LDBDCH(U)	;GET DEV CHARACTERISTICS
IFN FTNET,<
	TRNE	T1,LDRREM	;REMOTE LINE
	JRST	[PUSHJ P,NETDSF	;YES, LET NETSER DO IT
		 JRST CPOPJ1##]	;SKIP RETURN
>
	PUSHJ	P,CHKDSD	;(1)IS IT A MODEM
	JRST	TOPX4		;NO. CAN'T DO THIS.
	PUSHJ	P,LDBCLR	;CLEAR OUT LDB
	HRRZ	F,LDBDDB(U)	;DDB?
	JUMPE	F,TOPDF1	;NOT CONTROLLING JOB
	MOVE	T1,DEVMOD(F)
	TLNN	T1,TTYATC	;CONTROLLING TTY?
	JRST	TOPDF1		;NOPE
	PUSHJ	P,DSCDET	;DETACH IT
TOPDF1:	LDB	U,LDPDSC	;GET TABLE INDEX
	MOVSI	T1,DSCHWC	;CLEAR
	ANDCAM	T1,DSCTAB##(U)
	PUSHJ	P,DSROF1	;HANG IT UP
	JRST	CPOPJ1##	;AND SKIP RETURN

TOPDSS:	MOVE	T1,LDBDCH(U)	;CHARACTERISTICS
IFN FTNET,<
	TRNE	T1,LDRREM	;REMOTE?
	JRST	NETDSS		;YES, LET NETSER DO IT
>
	PUSHJ	P,CHKDSD	;(1)DATASET?
	JRST	TOPX4		;NO, LOSE
	LDB	U,LDPDSC	;DSCTAB OFFSET
	SKIPL	DSCTAB##(U)	;HARDWARE CARRIER?
	TDZA	T1,T1		;NO
	MOVSI	T1,DSCHWC	;YES
	JRST	STOTC1##	;STORE ANSWER FOR USER
IFE FTDIAL,<
	TOPDSC==CPOPJ##
>
IFN FTNET,<
	;CODE TO CONTROL REMOTE DATASET LINES
NETDSS:	MOVEI	T3,DSTSTS	;STATUS
	JRST	NETISR		;CALL NETSER
NETDSE:	MOVEI	T3,DSTON	;SET DATASET ON
	JRST	NETISR		;CALL NETSER
NETDSF:	MOVEI	T3,DSTOFF	;SET DATASET OFF
	JRST	NETISR		;CALL NETSER
NETDSC:	MOVEI	T3,DSTCRQ	;DIALER REQUEST
NETISR:	MOVEI	T1,ISRDSC	;DATASET CONTROL FUNCTION
	PJRST	D85DSC##	;CALL NETSER DIRECTLY SINCE NO DATASET TIMING
>
IFN FTDIAL,<
TOPDSC:
	MOVE	T1,LDBDCH(U)	;DEVICE CHARACTERISTICS
IFN FTNET,<
	TRNE	T1,LDRREM	;REMOTE LINE
	JRST	NETDSC		;YES
>
	TRNN	T1,LDRDSD	;DATASET?
	JRST	TOPX4		;NO. CAN'T DIAL THEN.
IFN FTMP,<
	PUSHJ	P,ONCPUL##	;MUST BE ON DEVICES OWN CPU
>
	LDB	U,LDPDSC	;GET DSCTAB INDEX
	MOVE	T1,DSCTAB##(U)	;AND BITS
	TLNE	T1,DSCHWC!DSCSWC	;ALREADY IN USE?
	JRST	TOPX5		;YES. CAN'T DIAL ON IT.
TOPDC1:	HRRZ	T1,DSCTAB##(U)	;GET TERMINAL NUMBER FOR MODEM
	CAME	T1,DSDUNI##	;BUSY FOR SAME UNIT, OR
	AOSN	TTYDDL##	;DIALLER FREE?
	JRST	TOPDC2		;YES
	MOVEI	T1,5		;NO. WAIT FOR IT.
	PUSHJ	P,SLEEP##	; ..
	JRST	TOPDC1		;TRY AGAIN
TOPDC2:	MOVEM	T1,DSDUNI##	;SAVE LINE BEING DIALLED
	PUSHJ	P,GETWRD##	;FROM USER CORE
	  JRST	TOPX3		;ADDRESS CHECK
	MOVEM	T1,DSCNUM	;STORE FOR DIALLER CODE
	HRRI	M,1(M)		;AND SECOND WORD
	PUSHJ	P,GETWRD##	; ..
	  JRST TOPX3		;ADDRESS CHECK
	TRO	T1,17		;GUARANTEE AN END OF NUMBER CODE
	MOVEM	T1,DSCNUM+1	;STORE SECOND WORD
	MOVSI	T1,DSCIC2	;CLEAR OUT THESE BITS
	ANDCAM	T1,DSCTAB##(U)	;IN CONTROL TABLE
	MOVSI	T1,DSCSWC!DSCDLW!↑D30
	IORM	T1,DSCTAB##(U)	;AND SET UP TO WAIT FOR DIALLER
	MOVE	T1,[POINT 4,DSCNUM]
	MOVEM	T1,TTYDDA##	;STORE INITIAL POINTER TO NUMBER
	MOVEI	T3,DSTCRQ	;CALL REQUEST CODE
	PUSHJ	P,DSCCAL	;TO THE DEVICE HANDLER
TOPDC3:	MOVEI	T1,↑D15		;SLEEP FOR FIFTEEN SECONDS
	PUSHJ	P,SLEEP##	; ..
	MOVE	T1,DSCTAB##(U)	;SEE WHAT HAPPENED.
	TLNE	T1,DSCDLF	;FAIL?
	JRST	TOPX5		;YES.
	TLNE	T1,DSCDLC	;COMPLETED OK?
	JRST	CPOPJ1##	;YES. SKIP RETURN TO USER
	JRST	TOPDC3		;NEITHER YET. LOOP.

> ;END OF FTDIAL
> ;END OF FTMODM
IFN FTCAFE!FTKS10,<

TOPABR:	MOVEI	T3,<LPCABR>B27	;SET UP FUNCTION
	MOVEI	T1,ISRLPC	;FUNCTION CODE
	SKIPGE	LDBISR(U)	;SKIP IF NOT DC76
	PUSHJ	P,@LDBISR(U)	;CALL SERVICE ROUTINE
	JRST	CPOPJ1##	;GIVE GOOD RETURN
>;IFN FTCAFE!FTKS10

;HERE TO SET TYPE ELEMENT IN 2741
IFN FT2741,<

;ASSUME THAT THE ELEMENT CAN BE SET.

TOPELE:	PUSHJ	P,GETWRD##	;GET SETTING.
	  JRST	TOPX3		;ADDRESS CHECK
	MOVE	T3,T1
	MOVEI	T1,ISRELE	;FUNCTION
	PUSHJ	P,@LDBISR(U)	;CALL ISR
	  JRST	TOPX2		;BAD NUMBER
	JRST	CPOPJ1##	;WIN
>;IFN FT2741
	SUBTTL	TTCALL AND TRMOP. -- TYPE INTO TTY ON BEHALF OF A USER

;	TOPMTY	TYPE A STRING ON BEHALF OF USER

;ADDR:	LINE NO.
;	[ASCIZ/STRING/]

TOPMTY:	PUSHJ	P,SAVE3##	;SAVE AN AC
	LDB	P1,LDPLNO	;LINE NUMBER
	PUSHJ	P,GETWRD##	;GET ADDRESS OF STRING
	  JRST	TOPX3		;ADDRESS CHECK
	HRRI	M,-1(T1)	;AND PUT IT IN M FOR FUTURE GETWD1'S
	HRROS	T1		;LEFT JUSTIFIED ASCIZ STRING
	PUSHJ	P,CKSTR##	;MAKE SURE ITS IN CORE AND LEGAL
	  JRST	TOPX3		;ADDRESS CHECK
	AOS	(P)		;GIVE GOOD RETURN

TOPMT1:	MOVE	P3,[POINT 7,P2]	;SET UP BYTE POINTER
	PUSHJ	P,GETWD1##	;GET NEXT WORD OF ASCIZ STRING
	MOVE	P2,T1		;AND SAVE IT
TOPMT2:	TLNN	P3,760000	;END OF CURRENT WORD?
	JRST	TOPMT1		;YES - GET NEXT ONE
	ILDB	T3,P3		;GET NEXT CHAR
	JUMPE	T3,PTSTRT	;END OF STRING, WAKE CONTROLLER
	MOVE	U,LINTAB##(P1)	;SET LDB ADDRESS
	PUSHJ	P,TOPTYP	;TYPE IT
	JRST	TOPMT2		;NEXT CHAR



;TOPTYP  --  TYPE ONE CHARACTER FOR USER
;CALL WITH CHARACTER IN T3, LDB IN U

TOPTYP::PUSHJ	P,PEVEN8	;COMPUTE THE PARITY
	MOVEI	T2,L1RMIF	;MIC INTERLOCK BIT
TOPMT3:	SCNOFF			;NO INTERRUPTS WHILE SETTING LOCK
	TDNE	T2,LDBBYT(U)	;CHECK INTERLOCK
	JRST	[SCNON		;ALLOW PENDING INTERRUPTS
		 JRST TOPMT3]	;TRY AGAIN
	IORM	T2,LDBBYT(U)	;SET THE INTERLOCK BIT
	SCNON			;AND ALLOW INTERRUPTS
	PUSHJ	P,RECINU	;GO AND TYPE IT
	MOVEI	T2,L1RMIF	;GET AND
	ANDCAB	T2,LDBBYT(U)	; CLEAR THE "MIC IS TYPING" FLAG
	POPJ	P,		;AND GO GET NEXT CHAR
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  SET/CLEAR LDBMIC

IFN FTMIC, <
;	MICCLR - CLEAR DOWN LDBMIC
;ADDR:	LINE NO.

;	MICSET - SET UP LDBMIC
;ADDR:	LINE NO.
;	STATUS
;
;	BOTH GIVE OLD CONTENTS OF LDBMIC IN ADDR+1

TOPMCL:	MOVEI	T1,LDRPTY	;A PTY?
	TDNE	T1,LDBDCH(U)
	PUSHJ	P,PTYOW##	;YES, TELL BATCON
	SETZ	T1,		;SET IMPLIED ZERO ARGUMENT
	JRST	TOPMS1		;JOIN MIC SET CODE

TOPMST:	PUSHJ	P,GETWRD##	;GET THE ARGUMENT
	  JRST	TOPX3		;ADDRESS CHECK
	PUSH	P,T1
	ANDI	T1,177
	CAMLE	T1,HIGHJB##	;ISOLATE JOB NUMBER
	  JRST	[POP P,T1
		 PJRST ECOD2##]	;RETURN ERROR CODE 2 (OUT OF RANGE)
	POP	P,T1
	TLZ	T1,LDLMTI!LDLMMM;CLEAR INTERNAL BITS
TOPMS1:	MOVSI	T2,LDLMIC	;GET THE MIC ACTIVE BIT
	SKIPE	T1		;...
	IORM	T2,LDBDCH(U)	; SET OR
	SKIPN	T1		;...
	ANDCAM	T2,LDBDCH(U)	; CLEAR AS NEEDED
	EXCH	T1,LDBMIC(U)	;SET NEW VALUE, RETURN OLD
	AOS	(P)		;GOOD RETURN
	PJRST	PUTWDU##	;GIVE USER OLD MIC WORD
;STILL IN IFN FTMIC
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  RETURN MIC STATUS

;	MICGET - GET STATUS
;ADDR:	LINE
;	RETURN RESULT TO ADDR+1

TOPMGT:	PUSHJ	P,SAVE1##	;SAVE AN AC
	SKIPN	P1,LDBMIC(U)	;IS MIC RUNNING US?
	JRST	TOPMG1		;NO FAIL RETURN
	HRRZ	F,LDBDDB(U)	;SET UP F
	JUMPE	F,TOPMG1	;ZERO MEANS HE LOGGED OUT -LOOSE HIM
	LDB	J,PJOBN##	;OTHERWISE - GET HIS JOB NO
IFN FTMP,<
	CAMN	J,COMJOB##	;ON THE SAME CPU AS US
	PUSHJ	P,ONCPU0##	;NO, GET HIM THERE
>
	PUSHJ	P,UJBSTX##	;GO GET JBTSTS
	TLZ	P1,LDLMMM!LDLMTI!LDLCL1	;CLEAR VOLATILE BITS
	TLNE	T1,(1B2)	;IN MONITOR MODE?
	TLO	P1,LDLCHK!LDLMMM;YES - SET FLAGS
IFN FTCIMP,<			;(163)
	SKIPE	LDBIMP(U)	;(163) XPATCHED?
	PUSHJ	P,MICIMP##	;(163) YES, SEE IF CONNECTION CAN EAT MORE
>;(163)
	TLNE	T1,(1B4)	;READY FOR I/P?
	TLO	P1,LDLCHK!LDLMTI;YES - SET FLAGS
IFN FTMLOG,<
	HRRZ	T1,LDBLOC(U)
	SKIPE	T1
	TLO	P1,LDLCHK!LDLCL1;SET TO FLAG
> ;END OF FTMLOG CONDITIONAL
	SKIPGE	LDBDDB(U)	;COMMAND WAITING?
	TLZ	P1,LDLMTI	;YES - CLEAR TI BIT
	MOVE	T1,P1		;PUT LDBMIC INTO T1 FOR
	AOS	(P)		;GOOD RETURN
	PJRST	PUTWDU##	;RETURNING TO USER

TOPMG1:	MOVSI	T1,LDLMIC	;THE CONTROLLED-BY-MIC BIT
	ANDCAM	T1,LDBDCH(U)	;CLEAR FOR XMTCHR
	SETZB	T1,LDBMIC(U)	;CLEAR DOWN LDBMIC
	PJRST	PUTWDU##	;AND EXIT
;STILL IN IFN FTMIC
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  READ ERROR RESPONSE TEXT

;	MICRSP : RECORD ERROR MESSAGE
;ADDR:	LINE NO.
;	ADDRESS OF SPACE TO RETRIEVE RESPONSE

TOPMRS:	SKIPE	T2,LDBMIC(U)	;RUNNING MIC
	TLNN	T2,LDLERC	;ERROR?
	JRST	TOPX4		;NO
	TLNN	T2,LDLRSY	;MAKE SURE GOT TO INT LEVEL WITH SYNC
	JRST	TOPX4		;NO

	PUSHJ	P,GETWRD##	;GET ADDRESS OF RESPONSE BUFFER
	  JRST	TOPX3		;ADDRESS CHECK
	PUSHJ	P,MICADC
	  JRST	TOPX3		;ADDRESS CHECK OF BUFFER
	PUSHJ	P,SAVE3##	;SAVE WORKING ACS
	MOVSI	P1,(<POINT 7,>)
	ADDI	P1,(T1)
	MOVEI	P2,<21*5>-1	;MAX SPACE IN BUFFER
	CAMLE	P2,LDBTOC(U)	;GOT THIS MANY?
	MOVE	P2,LDBTOC(U)	;NO - USE LESSER
	JUMPLE	P2,TOPX4	;NO CHARACTERS
	SKIPN	P3,LDBTOT(U)	;GET CHAR ADDRESS OF ERROR LINE
	JRST	TOPX4		;HASN'T GOT ONE?

TOPMR1:	LDCHK	T3,P3		;GET NEXT CHARACTER
TOPMR2:	EXCTUU	<IDPB T3,P1>
	JUMPE	T3,TOPMR3	;EXIT HAVING MADE ASCIZ
	SOJG	P2,TOPMR1	;GET NEXT CHAR
	SETZ	T3,		;MAKE ASCIZ
	JRST	TOPMR2

TOPMR3:	MOVSI	T1,LDLRSP!LDLRSY;CLEAR RESPONSE FLAG
	ANDCAM	T1,LDBMIC(U)
	AOS	(P)		;GOOD RETURN TO THE USER
	PJRST	TOPOKE		;START UP TERMINAL OUTPUT - GOOD EXIT
;STILL IN IFN FTMIC
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  LOG ALL TERMINAL OUTPUT

IFN FTMLOG,<

;	MICLOG: RECORD ALL UUO LEVEL OUTPUT
;ADDR:	LINE NUMBER
;	ADDR LOG BUFFER

TOPMLG:	SKIPE	T2,LDBMIC(U)	;RUNNING MIC?
	TLNN	T2,LDLLOG	;WANT LOG FEATURE?
	JRST	TOPX4

	PUSHJ	P,GETWRD##
	  JRST	TOPX3		;ADDRESS CHECK
	PUSHJ	P,MICADC	;ADDRRESS CHECK ALL OF BUFFER
	  JRST	TOPX3		;ADDRESS CHECK
	AOS	(P)		;SET FOR GOOD RETURN TO THE USER
	PUSHJ	P,SAVE2##	;SAVE WORKING ACS
	MOVSI	P1,440700
	HRRI	P1,(T1)
	MOVEI	P2,<21*5>-1

TOPML1:	SCNOFF			;DOWN PI SYSTEM
	SOSGE	LDBLOC(U)	;CHECK COUNT
	JRST	[SETZB T3,LDBLOC(U) ;FIX COUNT
		 JRST TOPML3]	;JOIN PROCESSING
	LDCHKR	T3,LDBLOT(U)	;TAKE A BYTE
TOPML3:	SCNON			;TURN PI'S BACK ON
TOPML2:	EXCTUU	<IDPB T3,P1>
	JUMPE	T3,XMTWAK
	SOJG	P2,TOPML1
	SETZ	T3,
	JRST	TOPML2		;LOOP UNTIL COUNT EXHAUSTED OR END BUFFER
> ;END OF FTMLOG CONDITIONAL
;STILL IN IFN FTMIC
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  MISCELLANEOUS MIC SUBROUTINES

IFN FTMLOG,<

; HERE WITH SCANNER INTERRUPTS DISABLED

MICLGC:	MOVE	T1,LDBMIC(U)	;GET MIC STATUS
	TLNN	T1,LDLLOG	;LOGGING?
	JRST	MICLG1		;NO-MIC HAS GIVEN UP MUST TIDY

	MOVE	T1,LDBTOP(U)	;MOVE TAKER TO PUTTER
	MOVEM	T1,LDBTOT(U)	;SO MIC CAN CATCH UP WITH PUTPUT
	MOVE	T1,LDBTOC(U)	;REMEMBER HOW MANY
	ADDM	T1,LDBLOC(U)	;KEEP TRACK FOR MIC
	JRST	MICLG2
;MIC HAS GONE AWAY MUST TIDY UP LOG BUFFER

MICLG1:	MOVE	T1,LDBLOT(U)	;MOVE PUTTER AND TAKER
	MOVEM	T1,LDBTOT(U)
	MOVEM	T1,LDBTOP(U)	;BACK UP
	SETZM	LDBLOT(U)	;ZAP LOG BUFFER
MICLG2:	SETZM	LDBTOC(U)	;ZAP COUNT
	JRST	SONPPJ		;AND EXIT
> ;END OF FTMLOG CONDITIONAL
;STILL IN IFN FTMIC

;SUBROUTINE TO ADDRESS CHECK A USER BUFFER

MICADC:	PUSH	P,M
	PUSH	P,T1
	HRRI	M,(T1)
	PUSHJ	P,GETWRD##
	  JRST	MICAD1
	HRRI	M,21(M)
	PUSHJ	P,GETWRD##
	TRNA
	AOS	-2(P)
MICAD1:	POP	P,T1
	JRST	MPOPJ##
;STILL FTMIC

;SUBROUTINE TO SET UP HORIZONTAL POSITION FOR MIC AND TO CHECK FOR
;OPERATOR AND ERROR CHARS IN COLUMN 1

MICPOS:	SKIPN	T2,LDBMIC(U)	;MIC RUNNING FOR THIS LINE?
	POPJ	P,		;NO, RETURN IMMEDIATELY
	PUSH	P,T3		;PRESERVE CHAR
	ANDI	T3,177		;MASK OFF PARITY
	PUSHJ	P,SPCHEK	;GET CHARACTERISTICS OF CHAR
	  JRST	MICPS2		;NOT SPECIAL
	TLNN	T1,CHCRET	;IS IT <CR>?
	JRST	MICPS1		;NOT - MUST CHECK OTHERS
	TLO	T2,LDLCL1	;SET COL 1 FLAG IN MICLDB
	MOVEM	T2,LDBMIC(U)
	JRST	T3POPJ##	;AND RETURN

MICPS1:	CAIE	T3,177		;IS IT A RUBOUT
	CAIN	T3,12		;OR LINE-FEED
	JRST	T3POPJ##	;YES - NO CHECKING
MICPS2:	TLZN	T2,LDLCL1	;ARE WE IN COLUMN 1?
	JRST	T3POPJ##	;NO - RETURN
	LDB	T1,LDP.OP	;GET OPERATOR CHAR
	JUMPE	T1,MICPS4	;JUMP IF NOT SET
	CAMN	T1,T3		;HAVE WE FOUND ONE?
	TLO	T2,LDLCHK!LDLOPC;YES - SET BITS
MICPS4:	LDB	T1,LDP.ER	;GET ERROR CHAR
	JUMPE	T1,MICPS3	;IF NO ERROR
	CAIE	T3,"?"		;"?" ERROR CHARACTER
	CAMN	T1,T3		;ONE OF THOSE?
	TLO	T2,LDLCHK!LDLERC;YES - SET ITS FLAGS
MICPS3:	MOVEM	T2,LDBMIC(U)	;STORE MIC WORD
	JRST	T3POPJ##	;RESTORE T3, AND RETURN
;STILL IN IFN FTMIC



;STILL FTMIC

IFN FTMLOG,<
;A ROUTINE TO FREE THE MIC LOG BUFFER IF REQUIRED

MLOGOF:	SKIPN	LDBLOT(U)	;HAS NOT GOT ONE
	POPJ	P,0
	SCNOFF			;SNEAKY PEEK
	SKIPE	LDBTOC(U)	;OUTPUT BUFFER IDLE
	JRST	SONPPJ		;NO FORGET IT
	JRST	MICLG1		;YES-GO ZAP LOG BUFFER AND TURN ON PI
> ;END OF FTMLOG CONDITIONAL

;ROUTINE TO WAKE MIC UP WHEN CONTROLLED JOB REQUIRES INPUT
MICWAK:	LDB	T1,LDPMJN	;LOAD MASTER JOB NO.
	CAMLE	T1,HIGHJB##	;JOB NUMBER TOO BIG?
	  JRST	MICWA1		;YES JUST RETURN
	MOVE	T2,JBTSTS##(T1)	;CHECK JOB STATUS
	TLNN	T2,JLOG		;LOGGED IN?
	  JRST	MICWA1		;NO JUST RETURN
	PUSHJ	P,WAKJOB##	;GO WAKE MIC
MICWA1:	MOVE	T1,LDBDCH(U)	;RESTORE C(U)
	POPJ	P,		;AND RETURN

MICECH:	TLNN	T1,CHCRET	;IS IT A <CR>?
	POPJ	P,		;NO, RETURN
	PUSH	P,T1		;SAVE T1
	MOVSI	T1,LDLCL1	;YES, SET COL 1 BIT
	IORM	T1,LDBMIC(U)	; IN LDBMIC
	JRST	TPOPJ##		;RETURN

MICRIC:	CONSO	PI,PI.IPA	;AT INTERRUPT LEVEL?
	POPJ	P,		;NO, THEN MIC TYPED IT
	CAIE	T3,1		;IS THE CHAR A ↑A
	CAIN	T3,201		;WITH POSSIBLE PARITY?
	JRST	MICRIA		;YES - GO DEAL WITH ↑A
	TLO	T1,LDLCHK!LDLMCC;SAY THAT ↑C WAS TYPED
	MOVEM	T1,LDBMIC(U)	;PUT IT BACK
	POPJ	P,		;AND RETURN
;STILL FTMIC

MICRIA:	TLO	T1,LDLCHK!LDLMCA;SAY ↑A
	MOVEM	T1,LDBMIC(U)	;PUT IT AWAY!
	TRC	T3,202		;CONVERT CHAR INTO A ↑C
	MOVSI	T1,CHBRK!CHCRE!CHCNC
	IORM	T1,-1(P)	;AND SET UP BITS TO LOOK LIKE ↑C
	POPJ	P,

PTYMCK:	CAIN	T3,20
	TLO	T2,LDLCHK!LDLMCP
	CAIN	T3,2
	TLO	T2,LDLCHK!LDLMCB
	MOVEM	T2,LDBMIC(U)
	TLNE	T2,LDLMCP!LDLMCB
	JRST	RICB3
	JRST	PTYPT1
> ;END IFN FTMIC

;CO-ROUTINE TO SETUP U AND .CPTOA SO THAT THE MONITOR CAN TYPE
; A COMMAND AT ITSELF.  USES LDB CORRESPONDING TO FRCLIN

FRCSET::EXCH	U,(P)		;GET CALLER'S PC, SAVE U
	PUSH	P,.CPTOA##	;SAVE .CPTOA
	MOVEM	U,1(P)		;WHERE TO RETURN TO CALLER
	MOVEI	U,TOPTYP	;PUT CHARS INTO INPUT
	MOVEM	U,.CPTOA##	; STREAM
	MOVE	U,LINTAB##+FRCLIN## ;LDB
	PUSHJ	P,@1(P)		;CALL CALLER AS A SUBROUTINE
	  CAIA			;NON-SKIP
	AOS	-2(P)		;PROPAGATE SKIP
	POP	P,.CPTOA##	;RESTORE .CPTOA
	JRST	UPOPJ##		;RESTORE U AND RETURN
	SUBTTL	SUBROUTINES FOR I/O

;SUBROUTINE TO READ A CHARACTER AND KEEP THE BREAK COUNT RIGHT
;
;IT IS ASSUMED THAT THE CALLER HAS DONE ANY NECESSARY WAITING. THERE
;ARE TWO UNUSUAL CASES: FIRST, IF THERE ARE NO CHARACTERS IN THE
;BUFFER, TYI WILL NON-SKIP RETURN. IF THE CHARACTER READ IS A
;CONTROL C, AND IF THE TERMINAL IS IN USER MODE, NOT SLAVED, NOT
;IN IMAGE INPUT STATE, AND NOT RUNNING UNDER JACCT, THEN TYI CALLS
;ROUTINES TO PUT CONSOLE AT MONITOR LEVEL, AND GOES BACK INTO I/O
;WAIT UNTIL A POSSIBLE CONTINUE COMMAND.
;
;IT IS THE CALLER'S RESPONSIBILITY TO EAT ANY POSSIBLE COMMAND LEFT
;LYING AROUND (I.E., CALL TYIEAT).
;
;TYICC USES P3! BE WARNED!

TYIS:	PUSHJ	P,SAVE3##	;REALLY SHOULD DO IT
	SETOM	P3		;FLAG DON'T WAIT IF NOTHING THERE
	JRST	TYICC2

TYI:	PUSHJ	P,SAVE3##
	TDZA	P3,P3		;FLAG WAIT ON ↑C, CONTINUE
TYICC:	TDZA	P3,P3		;FLAG WAIT ON ↑C, CONTINUE SEQUENCE
TYICC2:	SETZB	P1,P2		;INDICATE NO BUFFER
TYICC3:	TRNE	S,IODERR	;HAS HE GOTTEN A ↑C?
	POPJ	P,		;YES, FORGET IT
TYICC4:	SCNOFF			;NO RACES
	SOSGE	LDBTIC(U)	;ANY LEFT TO INPUT?
	JRST	TYICCZ		;FIX INPUT COUNT AND RESTORE PI
	LDCHKR	T3,LDBTIT(U)	;GET CHARACTER
	MOVE	T2,LDBTIT(U)	;INPUT TAKER POINTER
	CAMN	T2,LDBBKU(U)	;TAKEN LAST BREAK?
	SETZM	LDBBKU(U)	;YES, ZAP POINTER TO IT
	SCNON			;ALLOW INTERRUPTS
	PUSH	P,T3		;PRESERVE CHAR.
	SKIPG	LDBTIC(U)	;IS THIS THE LAST CHARACTER IN THE BUFFER
	PUSHJ	P,CHKXON	;YES, GO CHECK IF XON IS NEEDED
	POP	P,T3		;RESTORE CHAR.
	TRNE	T3,400		;IMAGE CHARACTER?
	JRST	CPOPJ1##	;YES, DONE HERE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

TYIC:
IFN FTCIMP,<			;(110)
	SKIPN	LDBIMP(U)	;(110) NO FURTHER PROCESSING IF XPATCHED
>;(110)
	PUSHJ	P,SPCHEK	;SEE WHAT KIND OF CHARACTER IT IS
	  JRST	CPOPJ1##	;NOTHING SPECIAL
	JUMPE	T3,TYICC4	;IF NULL, SKIP IT.
	TLNE	T1,CHALT	;SOME ALT CHAR?
	TLNE	U,LDLFCS	;FULL CHR SET?
	CAIA			;NO CONVERSION
	PUSHJ	P,RIALTO	;CONVERT
	TLNE	T1,CHBRK	;BREAK CHARACTER?
	SOS	LDBBKC(U)	;YES. COUNT IT DOWN.
	JUMPE	F,CPOPJ1##	;GOOD RETURN IF NO DDB
;IFN FTCIMP,<			;(110)
;	SKIPN	LDBIMP(U)	;(110) RETURN NOW IF XPATCHED
;>;(110)
	TLNN	T1,CHCNC	;CONTROL C CHARACTER?
	JRST	CPOPJ1##	;NO JUST RETURN TO CALLER
	MOVE	T1,DEVMOD(F)	;GET SOME BITS
	TLNN	T1,TTYATC	;IS TTY CONTROLLING A JOB?
	JRST	CPOPJ1##	;NO, RETURN CHAR
	HLL	U,LDBDCH(U)	;GET LINE STATE FLAGS
	PUSHJ	P,CNCCHK	;SEE IF IT IS A CONTROL C
	  JFCL			;YES, STORE
	  JRST	CPOPJ1##	;YES, BUT IT SHOULD BE STORED.
	MOVE	S,[XWD	IOW,IOACT]
	IORB	S,DEVIOS(F)
	SKIPN	P3		;WAIT?
	PUSHJ	P,TIWAIT	;NOW WAIT IN CASE TYPE CONTINUE
	PUSHJ	P,TYIEAT	;EAT THE CONTINUE COMMAND
	JUMPE	P1,TYICC3	;DONE IF NO PTR
	DMOVE	T1,P1		;SETUP BYTE POINTER AND COUNT SO PRNGE CAN
	PUSHJ	P,PRNGE##	;MAKE SURE BUFFER DIDN'T GO AWAY
				; (USER TYPED .CORE <SMALLER-VALUE> AND
				;  ZAPPED THE END OF HIS BUFFER)
	JRST	TYICC3		;LOOP AROUND AGAIN.


;HERE WITH THE PI SYSTEM TURNED OFF AFTER INPUT COUNT HAS BEEN
;FOUND EXHAUSTED.  (PROBABLY BY A SOSGE THAT DID NOT SKIP).

TYICCZ:	SETZM	LDBTIC(U)	;FIX CHARACTER COUNT
	SETZM	LDBBKU(U)	;CLEAR BREAK POSITION
	SETZM	LDBBKC(U)	; AND COUNT, SINCE EMPTY
	JRST	SONPPJ		;RESTORE PI AND NON-SKIP RETURN
;SUBROUTINE TO DISCARD A COMMAND FROM INPUT BUFFER IF L2RECS STILL ON

TYIEAT:	MOVEI	T1,L2RECS	;GET EAT CHARACTER SYNC BIT
	TDNN	T1,LDBBY2(U)	;STILL WANT COMMAND EATEN?
	POPJ	P,0		;NO. RETURN.
TYIL:	SCNOFF			;NO RACES
	SOSGE	LDBTIC(U)	;ANY CHARACTERS LEFT?
	JRST	[SETZM	LDBTIC(U)	;FIX COUNT
		SCNON		;LET WORLD BACK IN
		JRST	TYID]	; AND GIVE UP
	LDCHKR	T3,LDBTIT(U)	;TAKE A CHARACTER
	MOVE	T2,LDBTIT(U)
	CAMN	T2,LDBBKU(U)	;TAKEN LAST BREAK?
	SETZM	LDBBKU(U)	;ZAP POINTER
	SCNON			;ALLOW INTERRUPTS
	PUSHJ	P,SPCHEK	;GET CHARACTER DESCRIPTORS
	  JRST TYIL		;ORDINARY
	TLNE	T1,CHBRK	;BREAK CHAR?
	SOSA	LDBBKC(U)	;YES. COUNT IT AND QUIT
	JUMPN	T3,TYIL		;NO. LOOP IF STILL SOME TO GO
TYID:	MOVEI	T1,L2RECS	;NOW CLEAR THE BIT
	ANDCAM	T1,LDBBY2(U)	;IN THE DEVICE WORD
	POPJ	P,0
;HERE ARE THE ROUTINES TO PERFROM VARIOUS "TTY INPUT" FUNCTIONS

CTIGNC::PUSHJ	P,CTICOM	;GET THE NEXT CHARACTER (IN T3)
CTIGLC::PUSHJ	P,CTICOM	;GET THE "LAST CHAR COMCON READ" (IN T3)
CTISLC::PUSHJ	P,CTICOM	;SET THE "LAST CHAR" (FROM T3)
CTIGBP::PUSHJ	P,CTICOM	;GET THE BYTE POINTER BEING USED (IN T1)
CTISBP::PUSHJ	P,CTICOM	;SET THE BYTE POINTER TO USE (FROM T1)

CTICOM:	EXCH	T4,(P)		;SAVE "T4" GET OFFSET
	ANDI	T4,-1		;GET JUST THE ADDRESS
	SUBI	T4,CTIGNC+1	;MAKE IT 0 ORIGIONED
	ADD	T4,.CPTIV##	;GET ADDRESS OF TTY INPUT VECTOR TO USE
	XCT	(T4)		;CALL EITHER COMCON OR ONCE
	POP	P,T4		;RESTORE T4
	POPJ	P,		;  AND RETURN

;HERE IS THE "NORMAL" TTY INPUT VECTOR
COMTIV::PUSHJ	P,CCTYI		;CCTYI GET'S NEXT CHAR
	LDB	T3,LDPLCH	;LAST CHAR IS HERE
	DPB	T3,LDPLCH	; STILL HERE...
	MOVE	T1,LDBCLP(U)	;BYTE POINTER IS HERE
	MOVEM	T1,LDBCLP(U)	; STILL HERE...

;ROUTINE TO "GET NEXT CHAR" FROM NORMAL LINES
CCTYI::	SCNOFF			;NO RACES
	SKIPE	T2,LDBCLP(U)	;ADDRESS THERE TO USE?
	CAMN	T2,LDBTIP(U)	;YES. CAUGHT UP TO PUTTER?
	JRST	CCTYI1		;YES.  RETURN END OF LINE CHARACTER
	LDCHK	T3,LDBCLP(U)	;LOAD CHARACTER FROM TTCMCA POINTER
	JRST	SONPPJ		;ALLOW INTERRUPTS AND RETURN

CCTYI1:	MOVEI	T3,12		;RETURN BREAK CHAR
	JRST	SONPPJ
;SUBROUTINE TO SEE IF A CONTROL C SHOULD BE ACTED ON OR STORED.
;NON-SKIP MEANS STORE IT.
;SKIP MEANS JACCT SET
;DOUBLE SKIP MEANS .HALT DONE.

CNCCHK:	TLNE	U,LDLSLV+LDLIMI	;SHOULD ↑C BE RETURNED?
	POPJ	P,0		;YES.
	AOS	(P)		;ADVANCE RETURN
	PUSH	P,T1		;MAYBE NOT. SAVE T1.
	HRRZ	F,LDBDDB(U)	;GET LINE'S JOB
	JUMPE	F,CNCCK1	;IF NO DDB ATTACHED, ASSUME SHOULD DO ↑C
	LDB	T1,PJOBN##	; ..
	MOVE	T1,JBTSTS##(T1)	;GET JOB STATUS WORD
	TDNE	T1,[XWD JACCT,JS.DEP]	;IS ↑C LEGAL? (PRIVILEGED PROG OR
				; DAEMON ERROR PAUSE)
	JRST	TPOPJ##		;NO. GIVE IT TO CUSP

	PUSHJ	P,CNCMOD
CNCCK1:	PUSHJ	P,TTHALT	;FORCE CONTROL C
	JRST	TPOPJ1##	;RESTORE T1, SKIP RETURN

CLRIIQ:	HRRZ	F,LDBDDB(U)	;GET DDB, IF ANY.
	JUMPE	F,CLRIM1	;CLEAR BIT IF NO DDB
	MOVE	S,DEVIOS(F)	;GET STATUS WORD.
	TRNE	S,I		;IF STILL IMAGE, DON'T CLEAR BIT
	POPJ	P,0		;IMAGE. JUST RETURN
CLRIMI:	HRRZ	F,LDBDDB(U)	;GET ATTACHED JOB, IF ANY
	JUMPE	F,CLRIM1	;IF NONE, SKIP PART OF THIS
	MOVSI	S,FRCEND	;ALSO CLEAR FORCED END OF FILE BIT
	ANDCAB	S,DEVIOS(F)
CLRIM1:	MOVSI	T1,LDLIMI	;NO. CLEAR IMAGE BIT AND TIME
	DPB	T1,LDPTIM	; ..
	ANDCAM	T1,LDBDCH(U)	; ..
	PJRST	SETCHP		;TELL THE FRONT END AND RETURN
;ROUTINE TO PUT TERMINAL INTO MONITOR COMMAND MODE. DON'T CALL THIS
;ROUTINE IF TERMINAL IS A SLAVE, UNLESS YOU WANT SLAVE BIT CLEARED TOO.
;CALL WITH LINE SET.

CNCMOD::
IFN FTTVP,<PUSHJ P,CLRPCT>	;CLEAR PAGE COUNTER
	PUSHJ	P,STRTDL	;LET ONE DEFERRED LINE ECHO
	MOVEI	T1,L2RECS	;EAT RACE SYNC BIT
	ANDCAM	T1,LDBBY2(U)
	HRRZ	T1,LDBDDB(U)	;DDB ADDRESS
	JUMPE	T1,CNCMO2	;IF NO DDB, DON'T TRY TO TOUCH IT
	MOVEI	T2,PIMMOD	;MAKE SURE THAT PIMMOD
	ANDCAM	T2,DEVIOS(T1)	;ISN'T SET IN THE DDB
	MOVSI	T2,LDLBKA	;THE VOLATILE BREAK-ON-ALL-CHARACTERS BIT
	TDNN	T2,LDBDCH(U)	;IN CHARACTER MODE?
	TDZA	T2,T2		;NO
	MOVSI	T2,IOLBKA	;YES, REMEMBER THAT FACT
	IORM	T2,DEVIOS(T1)	;FOR TTYUSR TO FIND LATER
CNCMO2:	MOVE	T1,[LDLIMI+LDLNEC+LDLDLR+LDLBKA+LDLPIM,,LDROSU]
	ANDCAM	T1,LDBDCH(U)	;CLEAR ALL THESE BITS
	MOVSI	T1,LDLCOM	;AND SET THIS ONE
	IORB	T1,LDBDCH(U)	; ..
	TRNE	T1,LDRPTY	;IS THIS LINE PTY-DRIVEN?
	PUSHJ	P,PTMNMD##	;YES. TELL PTYSER ABOUT IT.
	PUSHJ	P,SETCHP	;BE SURE REMOTES ARE INFORMED
	PJRST	NOCTRO		;CLEAR ↑O AND RETURN


;SUBROUTINE TO SKIP IF TERMINAL IS AT COMMAND LEVEL AND NOT SLAVED

COMQ:	SKIPGE	LDBDDB(U)	;LDBCMR ON?
	JRST	CPOPJ1##	;YES. ASSUME COMMAND LEVEL
	HLL	U,LDBDCH(U)	;GET LINE STATE
	TLNE	U,LDLCOM	;AT TOP LEVEL?
	TLNE	U,LDLSLV	;AND NOT SLAVED?
	POPJ	P,0		;NO. JUST RETURN
	HRRZ	F,LDBDDB(U)	;IS LINE ATTACHED TO A JOB?
	JUMPE	F,CPOPJ1##	;JUMP IF NOT
	PUSH	P,T1		;SAVE AN AC
	MOVE	T1,DEVMOD(F)	;GET DEVICE ASSIGN BITS
	TLNE	T1,TTYATC	;ATTACHED TO JOB?
	JRST	TPOPJ1##	;YES. SKIP RETURN
	LDB	T1,PJOBN##	;IS JOB NUMBER ZERO?
	JUMPE	T1,TPOPJ1##	;IF SO,SKIP RETURN
	JRST	TPOPJ##		;IF NOT ATTACHED, CAN'T DO COMMAND
;ROUTINE TO MAKE THIS TERMINAL VISIBLE TO COMMAND DECODER, IF AT COM LEVEL
;CALL WITH LINE SET UP

COMSET::PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  POPJ	P,0		;NO. JUST RETURN
IFN	FTTVP,<PUSHJ P,CLRPCT>	;CLEAR PAGE COUNTER
	MOVSI	T1,LDBCMR	;OK. SET REQUEST BIT
COMST1:	SCNOFF			;CAN'T LOOK AT LDBDDB(U) HERE
COMSTF::SKIPL	LDBDDB(U)	;WAS COMMAND REQUEST ON?
	AOS	COMCNT##	;NO. WAKE COMCON
	IORM	T1,LDBDDB(U)	;SET THE BITS IN LDBDDB(U)
	SCNON			;FALL INTO CMDSET

;SUBROUTINE TO SET/CLEAR BIT IN COMMAND MAP

CMDSET::SKIPA	T1,[IORM T3,CMDMAP##(T2)]
CMDCLR::MOVE	T1,[ANDCAM T3,CMDMAP##(T2)]
	PUSH	P,T3		;SAVE T3
	SETZM	T3
	LDB	T2,LDPLNO	;GET LINE #
	LSHC	T2,-5		;SET TO WORD ADDRESS
	ROT	T3,5		;BIT WITHIN WORD
	MOVE	T3,BITTBL##(T3)	;GET THE BIT
	XCT	T1		;SET OR CLEAR
	PJRST	T3POPJ##	;RETURN
TTFCOM::				;FORCED COMMAND TABLE
PHASE 0
TTFCXC:!SIXBIT /.HALT/			;CONTROL C
IFN FTMODM!FTCIMP,<			;(110)
TTFCXD::!SIXBIT /.BYE/			;DATAPHONE DISCONNECT
TTFCXH::!SIXBIT /.HELLO/		;DATAPHONE CONNECT
>
TTFCXR::!SIXBIT /.RESTA/		;SYSTEM RESTART
TTFCXK:!SIXBIT /KJOB/			;FORCED KILL JOB
TTFCXI::!SIXBIT /INITIA/		;INITIALIZING CUSP CALL

IFN FTJCON,<
TTFCXJ::!SIXBIT /.FCONT/		;FORCED CONTINUE
>
IFN FTDAEM,<
TTFCXU::!SIXBIT /.DUMP/			;CCL RUN OF DUMP
>
TTFCXT:!SIXBIT	/.TYPE/			;RETYPE LINE
IFN FTWATCH,<
TTFCXW:!SIXBIT	/USESTA/		;1 LINE SYSTAT
>
IFN FTNET,<
TTFCXL::!SIXBIT	/.NETLD/		;AUTO DOWN LINE LOAD OF DAS80'S SERIES.
>
TTFCXS:!SIXBIT	/HALT/			;STOP JOB REGARDLESS OF ↑C TRAPPING


IFN FTCIMP,<				;(110)
TTFCXF::!SIXBIT	/.FTPSV/		;(110) ICP WANTS FTP SERVER
TTFCXN::!SIXBIT	/.NOOLD/		;(110) TELL LUSER WE DON'T SUPPORT
					;(110) OLD TELNET
TTFCXG::!SIXBIT	/FINGER/		;(110) SUPPORT A FINGER SERVER
>;(110)
IFN FTPATT,<
TTFCXX:!SIXBIT /CTEST/			;FOR PATCHING
>
DEPHASE
TTFCML==:.-TTFCOM
MTTFCM==:-TTFCML				;MINUS LENGTH OF FORCED COMMAND TABLE
IFG TTFCML -20,<PRINTX ?TOO MANY FORCED COMMANDS!>
	SUBTTL	COMMAND LEVEL ROUTINES

;ROUTINE TO SET UP TO READ A COMMAND FROM ANY REQUESTING LINE
;CALL FROM CLOCK LEVEL:
;	PUSHJ P,TTYCOM
;	  NONE FOUND
;	FOUND ONE	;F, U SET UP. J HAS JOB # IF ANY,
;			;T2 HAS TYPEIN T2

TTYCOM::MOVE	T1,BITTBL##+<FRCLIN##-<FRCLIN##/↑D32>*↑D32>
	TDNN	T1,CMDMAP##+<FRCLIN##/↑D32>
	SKIPA	T1,LINSAV##
	MOVEI	T1,FRCLIN##	;DO SYSTEM COMMANDS FIRST
	MOVEM	T1,LINSAV##
	CAIL	T1,TTPLEN##	;GREATER THAN HIGHEST LINE #?
TTYCM0:	SETZB	T1,LINSAV##	;YES, START AT LINE 0
	LSH	T1,-5		;SHIFT TO RIGHT PLACE
	HRLI	T1,TTCMPT##(T1)	;FORM AN AOBJN POINTER
TTYCM1:	SKIPE	T2,CMDMAP##(T1)	;GET A WORD OF BITS
TTYCM2:	JFFO	T2,TTYCM3	;FIND FIRST ONE BIT
	AOBJN	T1,TTYCM1	;LOOP TO TOP OF TABLE
	SKIPE	LINSAV##	;LOOKED AT THE ENTIRE TABLE?
	JRST	TTYCM0		;NO, START AT THE BEGINNING
	POPJ	P,0		;GIVE FAIL RETURN
TTYCM3:	MOVEI	T4,(T1)		;COPY WORD #
	LSH	T4,5		;SHIFT TO RIGHT PLACE
	ADDI	T4,(T3)		;ADD IN BIT NUMBER
	CAML	T4,LINSAV##	;SKIP IF LINE IS TOO SMALL
	JRST	TTYCM4		;ELSE FIX # AND PROCESS
	TDZ	T2,BITTBL##(T3)	;CLEAR BIT
	JRST	TTYCM2		;AND TRY NEXT
TTYCM4:	MOVEM	T4,LINSAV##	;SAVE THIS LINE #
	AOS	(P)		;GIVE SKIP RETURN
TTCM4A:	HRRZ	U,LINTAB##(T4)	;PICK UP LDB POINTER
TRESCN::HRRZ	F,LDBDDB(U)	;GET DDB ADDRESS IF ANY
	JUMPE	F,TRESC1	;JUMP IF NO DDB
	MOVE	T3,DEVMOD(F)
	TLNN	T3,TTYATC
TRESC1:	TDZA	J,J
	LDB	J,PJOBN##
IFN FTNET,<			;NETWORK AUTO-DISCONNECT FEATURE
	SETZ	T2,		;GET A ZERO FOR THE TIMER
	MOVE	T3,LDBDCH(U)	;GET THE DEVICE CHARACTERISTICS
	TRNE	T3,LDRREM	;IS A REMOTE TTY?
	DPB	T2,LDPADT	;  IF IT IS, THEN CLEAR HIS TIMER
>
	MOVE	T3,LDBDDB(U)	;KILL OR COMMAND?
	TLNN	T3,LDBCMF!LDBDET;FORCED COMMAND OR CLEANUP REQUIRED?
	TLNN	T3,LDBCMK	;NO, FORCED KJOB?
	JRST	TTYCM7		;NO.
	JRST	TTYCM5		;FORCED KJOB!
;DO FORCED COMMANDS OR CLEANUP 1ST, THEN FORCED KJOBS, THEN TYPED-IN COMMANDS

TTYCM7:	HRRM	U,.CPCML##	;MUST BE SAVED WHEN TTCMCA IS USED
	MOVE	T1,LDBTIT(U)	;GET TYPEIN CHAR ADR
	PUSHJ	P,CTISBP	; AND DEFINE IT AS THE INPUT BYTE POINTER
	HRRI	T3," "		;PRIME THE TYI ROUTINE
	TLNE	T3,LDBCMF	;FORCED COMMAND?
	MOVEI	T3,12		;YES. PREVENT EXTRA ARGUMENTS
	PUSHJ	P,CTISLC	;SAY IT IS LAST CHAR READ
	PUSHJ	P,FNDPDB##	;ADDRESS OF PDB
	  JFCL
	POPJ	P,0

TTYCM5:	MOVEI	T1,TTFCXC	;FORCE HALT 1ST SINCE IF TTKJOB IS CALLED DURING A COMMAND
	SKIPGE	JBTSTS##(J)	;MUST BE A JOB.  IS IT RUNNING
	JRST	TTYCM6		;NO.  JUST KILL IT
	MOVSI	T1,LDBCMK	;CLEAR KILL
	ANDCAM	T1,LDBDDB(U)	;FLAG
	MOVEI	T1,TTFCXK
TTYCM6:	PUSHJ	P,TTFORC	;FORCE COMMAND

;DON'T CALL CMDCLR, OR DELAYED COMMAND WILL NEVER BE SEEN AGAIN

	MOVE	T4,LINSAV##	;FIND LINE
	JRST	TTCM4A		;AGAIN
TTKJOB::PUSHJ	P,CNCMOD	;CONSOLE TO COMMAND LEVEL
	MOVSI	T1,LDBCMK	;SET KILL REQUEST
	IORM	T1,LDBDDB(U)	;IN LDB
	HRRZ	F,LDBDDB(U)
	SKIPE	J,F
	LDB	J,PJOBN##
	AOS	COMCNT##	;MAKE COMCON SEE IT
	SKIPL	JBTSTS##(J)	;SKIP IF JOB IS IN RUN STATE
				; THIS DEPENDS UPON:
				; 1. RUN BIT BEING SIGN OF JBTSTS
				; 2. J=0 IF NO JOB
				; 3. JBTSTS+0 = 0
	PJRST	CMDSET


;TTHALT  --  HALT THE JOB ATTACHED TO THE TERMINAL
;
;THIS ROUTINE DOES NOT SET TERMINAL TO COMMAND LEVEL BECAUSE JACCT
;PROGRAMS MAY STILL NEED TO TYPEOUT AND THAT WOULD BLOCK THEM IN TO STATE.

TTHALT:	MOVEI	T1,TTFCXC	;HALT COMMAND INDEX
	PJRST	TTFORC		;FORCE THE ↑C
;ROUTINES TO ATTACH TERMINAL TO A JOB

;1) CALL WHEN COMMAND DECODER DECIDES TO CREATE A JOB DUE TO
;A COMMAND BEING TYPED IN. THE LDB WILL ALREADY HAVE BEEN
;SET UP, BUT IT IS NOT YET LINKED TO A DDB
;
;CALL:	MOVE LINE,ADDRESS OF LDB
;	MOVE J,NEW JOB NUMBER
;	PUSHJ P,TTYATI
;	  ERROR RETURN	;ALREADY SOMEONE THERE (DDB POINTS AT HIM), OR
;			;NO MORE FREE DDB'S (DDB CONTAINS 0)
;	OK RETURN	;DDB, DDBLDB, AND LDBDDB SET UP
;
;2) CALL FROM COMMAND DECODER ON AN ATTACH COMMAND.
;
;CALL:	MOVE LINE,ADDRESS OF LDB
;	MOVE J,JOB TO ATTACH TO
;	PUSHJ P,TTYATT
;	  ERROR RETURN	;SOMEONE ALREADY ATTACHED (DDB POINTS TO HIM) OR
;			;NO SUCH DDB (DDB=0)
;	OK RETURN	;DDB, LDBDDB, NEW DDBLDB SET UP. OLD DDBLDB CLEARED

IFN FTATTACH,<

TTYATT::PUSH	P,U
	PUSHJ	P,TTYISA	;SEE IF DDB FOR TARGET JOB CAN BE ATTACHED
	  JRST	LPOPJ##		;NO, CAN'T DO IT
IFE FTPI,<JUMPE T1,TTYAT2>	;JUMP IF NO JOB IS ATTACHED TO LINE
IFN FTPI,<JUMPE T1,TTYAT1>	;JUMP IF DETACHED BUT SIGNAL DETACHING
	MOVEM	T1,(P)		;SAVE LDB OF TARGET JOB
	LDB	T1,LDPLNO	;OPERATOR DOING PREEMPTIVE ATTACH
				; GET OPERATOR'S LINE NUMBER
	EXCH	U,0(P)		;GET LDB OF OBJECT JOB
	LDB	T3,LDPLNO	;GET ITS LINE NUMBER TOO
	CAIE	T3,0(T1)	;ARE THEY THE SAME? (OPR ATTACHING
				; TO HIMSELF?)
	PUSHJ	P,PTYDET	;NO. DETACH OBJECT JOB, NOW IN LINE.
				; MUST RESPECT F
				;F NOW POINTS TO JOB BEING
				;PICKED UP BY TERMINAL IN 0(P)
	JRST	TTYAT2		;GO DO THE ATTACH
IFN FTPI,<
TTYAT1:	PUSHJ	P,SIGDET	;SIGNAL DETACHING
	JRST	TTYAT2		;GO DO THE ATTACH
>
> ;END IFN FTATTACH
TTYATI::
IFN FTMP,<
	PUSHJ	P,INTLVL##	;IF AT UUO LEVEL
	  PUSHJ	P,ONCPU0##	;AVOID RACES WITH COMCON
>
	PUSH	P,U		;SAVE LINE DATA BLOCK ADDRESS
	PUSHJ	P,TTYSRC	;SEE IF THERE'S ALREADY A DDB. SHOULDNT BE.
	  PUSHJ P,DDBSRC	;OK. GET A NEW DDB.
	    JRST LPOPJ##	;ERROR. EITHER TTYSRC WON OR DDBSRC LOST
TTYAT2:	MOVE	U,0(P)		;GET LDB ADDR FROM STACK
	PUSH	P,F		;AND SAVE NEW DDB ADDRESS
	HRRZ	F,LDBDDB(U)	;GET OLD DDB IF ANY
	SKIPE	F		;ANY THERE?
	PUSHJ	P,TTYDT1	;YES. DETACH FROM IT BUT DON'T SET MONITOR CODE
	SKIPN	U		;SKIP IF LDB WAS FOUND
	PUSHJ	P,TTYKLQ	;NO, KILL OFF DDB
	MOVE	F,0(P)		;RESTORE NEW DDB ADDRESS
IFN FTMODM,<
	MOVE	U,-1(P)		;GET LDB ADDRESS, FOR DS POINTER
	MOVSI	T1,LDBCMF
	TDNE	T1,LDBDDB(U)
	JRST	TTYAT3
;(1)	MOVE	T1,LDBDCH(U)	;LOOK AT DATA SET BIT
;(1)	TRNN	T1,LDRDSD	;IF NOT A DATA SET
	PUSHJ	P,CHKDSD	;(1)
	JRST	TTYAT3		;NO DSCTAB ENTRY
	LDB	U,LDPDSC	;GET DATASET TABLE INDEX
	MOVEI	T1,0		;CLEAR TIME FIELD OF DATASET ENTRY
	DPB	T1,DSTMPL	; ..
>
TTYAT3:	MOVE	U,-1(P)		;ATTACH LDB FROM STACK TO DDB
	MOVE	T1,[XWD TTYATC,ASSCON]	;SET ATTACHED AND ASSIGNED BITS
	IORM	T1,DEVMOD(F)	;IN THE DEV DATA BLOCK
	HRRM	F,LDBDDB(U)	;SET LINK FROM DDB TO LDB
	HRRM	U,DDBLDB(F)	;AND LINK FROM LDB TO DDB
	PUSHJ	P,SETDVL##	;AND JOB NUMBER IN DDB
	HRRZM	F,TTYTAB##(J)	;STORE CONTROLLING DDB BY JOB NUMBER
	PUSHJ	P,SCNNAM	;SET UP PHYSICAL LINE NAME AND PUNIT
IFN FTNET,<PUSHJ P,SETSTA>	;SET CORRECT STATION NUMBER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;THIS CODE MAKES SURE BATCH BIT STAYS CORRECT

IFN FTATTA&FTTLIM,<
	PUSHJ	P,CTLJBU##	;GET PTY DDB IF ANY
;(254)	JUMPL	T1,TTYAT5
	JUMPL	T1,TTYAT4	;(254) not a PTY
	MOVSI	T1,DVDIBP	;GET BATCH PTY BIT
	MOVE	T2,JBTLIM##(J)	;GET JBTLIM
	TDNN	T1,DEVCHR(F)	;IS IT A BATCH PTY?
	JRST	TTYAT4		;NO
	TLON	T2,(JB.LBT)	;YES, MAKE IT A BATCH JOB
	AOS	BATNUM##	;INCREMENT # OF BATCH JOBS
	MOVEM	T2,JBTLIM##(J)	;RESTORE JBTLIM
TTYAT4:
> ;END FTATTA&FTTLIM&FTPTYUUO

IFN FTPI,<PUSHJ	P,SIGDET>	;SIGNAL ATTACH (SAME AS DETACH)

TTYAT5:
IFN FTCIMP,<			;(110)
	MOVEI	T1,LDRIMP	;(110) IMP CONNECTION?
	TDNE	T1,LDBDCH(U)	;(110) ....
	PUSHJ	P,IMPATT##	;(110) YES - LINK UP
>
	POP	P,F
IFN	FTTLIM,<
	MOVSI	T1,(JB.LTL)	;GET DETACH TIME UNIT BIT
	TDNN	T1,JBTLIM##(J)	;SEE IF SET
	  JRST	TTYAT6		;NO -- LEAVE ALONE
	ANDCAM	T1,JBTLIM##(J)	;YES -- CLEAR IT
	MOVEI	T1,0		;NO TIME UNIT NOW
	DPB	T1,JBYLTM##	;CLEAR
TTYAT6:
> ;END IFN FTTLIM
	JRST	UPOPJ1##	;SKIP RETURN TO COMCON.
;SUBROUTINE TO LOOK FOR POSSIBLE LINE ALREADY ATTACHED TO TARGET JOB
;ARGS	U=LINE ATTACH WAS TYPED OR
;	J=JOB NUMBER OF TARGET JOB
;VALUES	T1=ADDR OF LDB ATTACHED TO TARGET JOB OR 0 IF NONE
;NON-SKIP RETURN IF NO DDB FOR TARGET JOB OR DDB FOUND BUT MANY NOT ATTACH
;SKIP RETURN IF DDB FOUND AND MAY ATTACH TO IT

TTYISA::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,U		;SAVE LINE BLOCK ADR OF GUY TYPING COMMAND
	PUSHJ	P,TTYSRC	;FIND THE DDB CONTROLLING THAT JOB
	  JRST LPOPJ##		;THERE ISN'T ANY. COMCON HAS GOOFED?
	SETZ	T1,
	JUMPE	U,LPOPJ1##	;IF NONE ATTACHED, GO ATTACH.
	EXCH	U,0(P)		;SOMEONE IS ATTACHED. ONLY THE OPERATOR
				;MAY USURP THE EXISTING CONNECTION
	PUSH	P,F		;SAVE NEW DDB
	HRRZ	F,LDBDDB(U)	;DDB OF OLD USER
	SKIPE	T1,F		;IF F=0, MAKE T1 0, SINCE PJOBN IS MEANINGLESS IF F=0
	LDB	T1,PJOBN##	;HIS JOB NUMBER
	LDB	P1,LDPLNO	;GET TERMINAL LINE # IN P1
	SUBI	P1,PTYOFS##	;SUBTRACT OFFSET OF PTY0
	JUMPL	P1,TTYIS1	;SEE IF A PTY
	CAIGE	P1,PTYN##	; ..
	SKIPA	F,PTYTAB##(P1)	;IT IS A PTY, GET DDB
TTYIS1:	TDZA	P1,P1		;NOT A PTY, USE JOB 0
	LDB	P1,PJOBN##	;GET JOB OWNING PTY
	POP	P,F		;RESTORE F
	MOVE	P2,FSFPPN##	;GET [1,2]
	CAME	P2,JBTPPN##(T1)	;IS JOB THAT TYPED COMMAND [1,2]?
	CAMN	P2,JBTPPN##(P1)	;OR COMMAND TYPED BY SON OF OPR?
	JRST	TPOPJ1##	;YES, ATTACH IS LEGAL

	HRRZ	T1,OPRLDB##
	CAIE	T1,0(U)		;IS THIS THE OPR?
	JRST	TPOPJ##		;NO. DISCARD OBJECT JOB'S LDB FROM
	JRST	TPOPJ1##	;STACK, AND GIVE ERROR RETURN TO COMCON
				;WITH DDB POINTING AT GUY ALREADY ATTACHED
;ROUTINE TO DETACH TERMINAL FROM A JOB.
;CALL:	MOVE F,ADDRESS OF TTY DDB TO BE DETACHED
;	MOVE U,LDB  ADDRESS IF ENTRY AT PTYDTC
;	PUSHJ P,TTYDET
;	ALWAYS RETURN HERE

;CALLED FROM TTYATT AND COMCON (DETACH COMMAND)
;KILLS DDB IF NOT ATTACHED, ASSIGNED, OR INITED
;CLEARS LINKS TO DDB
;RESPECTS DDB


TTYDTC::TDZA	T2,T2		;FLAG TTYDTC ENTRY
TTYDET::MOVEI	T2,1		;SAME FOR TTYDET
IFN FTPI,<
	PUSH	P,T2		;SAVE T2
	PUSHJ	P,SIGDET
	POP	P,T2		;RESTORE IT
>
	HRRZ	U,DDBLDB(F)	;GET LDB ADDRESS
	LDB	T1,LDPLNO	;GET LINE NUMBER
	CAIN	T1,FRCLIN##	;RUNNING ON FRCLIN?
	JRST	@[EXP PTYDTC,PTYDET](T2)  ;YES, SKIP LOGGED OUT CHECK
	LDB	T1,PJOBN##	;GET JOB NUMBER
	MOVE	T1,JBTSTS##(T1)	;IS HE LOGGED IN?
	TLNE	T1,JLOG		; ..
	JRST	@[EXP PTYDTC,PTYDET](T2) ;YES, DISPATCH TO PTYDET
	LDB	T2,PJOBN##	;GET JOB NUM
	MOVE	T1,[SIXBIT/LOGOUT/]	;DON'T CLEAR
	CAMN	T1,JBTNAM##(T2)	;FOR LOGOUT SINCE USER COULD
	JRST	TTKJOB		;THEN GET OUT OVER QUOTA
	MOVSI	T1,JACCT	;CLEAR JACCT
	ANDCAM	T1,JBTSTS##(T2)	;IN STATUS
	JRST	TTKJOB		;GO KILL HIM
PTYDTC::LDB	T1,PJOBN##	;GET JOB NUMBER FROM DDB
	MOVSI	T2,CMWB		;AND COMMAND WAIT BIT
IFN FTMP,<CAME T1,COMJOB##>	;CURRENT JOB IN COMCON?
	TDNE	T2,JBTSTS##(T1)	;OR JOB IN COMMAND WAIT?
	JRST	[MOVSI	T1,LDBDET ;TELL COMRET TO CLEAN UP
		 IORM	T1,LDBDDB(U) ;JOB/COMMAND AT COMMAND EXIT
		 PJRST	DETCHK]	;WAIT FOR DETACH AND RETURN
PTYDET::PUSHJ	P,TTYDT1	;DISCONNECT DDB FROM LDB
	JUMPE	U,TTYKLQ	;IF NO LDB KILL OFF DDB
	PUSHJ	P,CNCMOD	;MAKE SURE LDB AT TOP LEVEL

;ROUTINE TO KILL DDB IF IT IS AN IDLE TTY DDB


TTYKLQ::PUSH	P,T1		;RESPECT T1
	MOVE	T1,DEVMOD(F)	;GET DEVICE MODE AND USE BITS
	TLNE	T1,DVTTY	;IS IT A TTY DDB?
	TDNE	T1,[XWD TTYATC,ASSCON+ASSPRG]	;YES, ANY REASON TO KEEP DDB?
	JRST	TPOPJ##		;YES.
	PUSHJ	P,TTYKIL	;NO. GO KILL THE DDB
	JRST	TPOPJ##		;AND RESTORE T1 ON RETURN
;SUBROUTINE TO DISCONNECT A TERMINAL FROM A JOB WITHOUT SETTING TERMINAL TO MONITOR LEVEL
;THIS IS SO ATTACH UUO WILL LEAVE TERMINAL AT ITS ORIGINAL LEVEL (MONITOR OR USER MODE)

TTYDT1:	HRRZ	U,DDBLDB(F)	;GET LINKED LINE ADDRESS
	HLLZS	DDBLDB(F)	;DISCONNECT LDB FROM DDB
	JUMPE	U,TTYDTX	;IF NO LDB, KILL OFF DDB
	HLLZS	LDBDDB(U)	;DISCONNECT DDB FROM LDB
	HRRZS	DEVNAM(F)	;CLEAR LH OF DEVNAM TO NOT CONFUSE DEVCHR, ETC.
				;KEEP RH FOR SYSTAT, ETC.
IFN FTDAEM!FTTLIM,<
	LDB	T1,PJOBN##	;SEE IF THIS JOB WAITING FOR DAEMON
>
IFN FTTLIM,<
	MOVSI	T2,(JB.LBT)	;BATCH BIT
	TDNE	T2,JBTLIM##(T1)	;IF WAS BATCH JOB
	SOS	BATNUM##	;DECR. BATCH JOB COUNT
	ANDCAM	T2,JBTLIM##(T1)	;CLEAR BIT SO OPERATOR CAN DETACH
>
IFN FTDAEM,<
	MOVE	T1,JBTSTS##(T1)	;GET JOB STATUS WORD
	TRNN	T1,JDC		;DCORE COMMAND WAITING?
>
	PUSHJ	P,TYIEAT	;NO. CLEAR ANY PENDING COMMAND
	MOVE	T1,LDBDCH(U)	;GET LINE CHARACTERISTICS
	TRNE	T1,LDRPTY	;A PTY LINE?
	PUSHJ	P,PTMNMD##	;YES. WAKE CONTROLLER
TTYDTX:	POPJ	P,

IFN FTPI,<
SIGDET:	SIGNAL	C$DATT
	  POPJ	P,
	POPJ	P,
>

;ROUTINE TO MAKE SURE A LINE IS DETACHED BEFORE PROCEDING
;CALL WITH U POINTING AT THE LDB IN QUESTION
DETCHK:	PUSH	P,J		;SAVE J
	MOVE	J,.CPJOB##	;SET TO CURRENT JOB
DETCH1:	MOVSI	T1,LDBDET	;WAITING FOR COMMAND
	TDZN	T1,LDBDDB(U)	; TO COMPLETE?
	JRST	JPOPJ##		;NO
	PUSHJ	P,SLEEPF##	;YES, WAIT UNTIL ITS DONE
	JRST	DETCH1		;TRY AGAIN
;ROUTINE TO RELEASE A TTY DDB. CALL WITH DDB SET UP.


TTYREL::MOVE	T1,[XWD IOW,IOACT]	;CLEAR OUT S
	ANDM	T1,DEVIOS(F)	; IN CORE
	SKIPE	DINITF##	;IN SYSINI?
	JRST	TTYRL2		;YES--SKIP THIS
	PUSHJ	P,SAVE1##	;SAVE CHANNEL NUMBER
	MOVEI	P1,0		;START AT CHANNEL ZERO
TTYRL0:	PUSHJ	P,NXTCH##	;NEXT CHANNEL
	  JRST	TTYRL1		;ALL CHANNELS HAVE BEEN LOOKED AT
	SOS	P1		;ADJUST P1
	CAIN	P1,@-1(P)	;CHANNEL BEING RELEASED
	AOJA	P1,TTYRL0	;YES
	CAIE	T1,(F)		;NO SAME DDB OPEN ON ANOTHER CHANNEL?
	AOJA	P1,TTYRL0	;NO
	JRST	TTYRS1		;YES, DON'T MAKE THE DDB GO AWAY
TTYRL1:
IFN FT2741&FTCAFE <
	HRRZ	U,DDBLDB(F)	;GET LINE BLOCK ADR
	JUMPE	U,TTYRL2	;BYPASS IF NONE
	MOVSI	T1,LILAPL	;BIT FOR APL MODE
	ANDCAM	T1,LDBISR(U)	;CLEAR APL MODE
>;END OF IFN FT2741
TTYRL2:	MOVE	T1,[XWD TTYATC,ASSCON]	;IS TTY ATTACHED OR ASSIGNED?
	TDNE	T1,DEVMOD(F)	; ..
	JRST	TTYRS1		;YES. KEEP DDB AROUND. RETURN.
;	JRST	TTYKIL		;NO. GO DISCARD DDB.
;ROUTINE TO CLEAR A TTY DDB AND MAKE IT AVAILABLE TO THE POOL
;CALL:	MOVE F,ADDRESS OF DEVICE DATA BLOCK KNOWN TO BE THROUGH USE.
;	PUSHJ P,TTYKIL
;	ALWAYS RETURN HERE
;RESPECTS F & S, CLOBBERS T1


TTYKIL::SETZM	DEVNAM(F)	;CLEAR PHYSICAL NAME
	SETZM	DEVLOG(F)	;CLEAR LOGICAL NAME
	MOVSI	T1,IOFST	;INITIAL STATE OF S WORD
	MOVEM	T1,DEVIOS(F)	;PLACE IN CORE STATUS WORD
IFN FTPI,<
	SKIPE	DEVPSI(F)	;USER INTERRUPTING ON THIS
	PUSHJ	P,PSIRMV##	;YES, REMOVE PSI LINKS
>
	PUSHJ	P,CLRDVL##	;NO JOB OWNS IT ANY MORE.
IFN FTLINK,<			;(111)
	PUSHJ	P,LNKBRK##	;(111) CUT OFF LINKS
>;(111)
	PUSH	P,U
	HRRZ	U,DDBLDB(F)	;GET LINK TO LINE DATA BLOCK
	JUMPE	U,TTYKL1	;BYPASS IF NO LINK.
	PUSHJ	P,TTYSTC	;PUT LINE AT COMMAND LEVEL
	PUSHJ	P,TTYCPT	;CLEAR PAPER TAPE BITS
	MOVSI	T1,LPLCLR	;CLEAR PAGE BITS
	ANDCAM	T1,LDBPAG(U)	;SO XON AND XOFF ARE ECHOED PROPERLY
	MOVSI	T1,LDLSSO	;CLEAR THE STOP OUTPUT BIT	
	ANDCAM	T1,LDBDCH(U)	;IN THE DCH WORD
	HLLZS	LDBDDB(U)	;REMOVE LINK TO DEAD DDB
IFN FTCIMP,<			;(110)
	SETZM	LDBIMP(U)	;(110) CLEAN UP IMP PARTS OF LDB
	SETZM	LDBQUO(U)	;(110) ....
>;(110)
	PUSHJ	P,CLRIM1	;MAKE SURE NOT IN IMAGE MODE
	PUSH	P,S		;IN CASE SOME CALLER SOMEWHERE CARES
	MOVEI	S,0		;CLEAR ALL THOSE BITS IN LDBDCH
	PUSHJ	P,UUOLDB	;CLEAR OUT LDB
	POP	P,S		;THIS IS REALLY SUPERCAUTION
TTYKL1:	HLLZS	DDBLDB(F)	;REMOVE LINK FROM DDB TO LINE DATA BLOCK
	MOVE	T1,[XWD TTYUSE+TTYATC,ASSCON+ASSPRG]
	ANDCAB	T1,DEVMOD(F)	;LAST CLEAR THESE, MAKING DDB AVAILABLE
	JRST	UPOPJ##		;AND RETURN TO CALLER.
;SUBROUTINE CALLED ON RESET FROM UUOCON


TTYRES::PUSHJ	P,SAVE1##
	MOVEI	P1,JS.NTO
	TDNE	P1,JBTSTS##(J)
	XORB	P1,JBTSTS##(J)
	ANDI	P1,JS.NTO
	MOVEI	F,SCNDDB
TTYRSA:	LDB	T1,PJOBN##
	CAIE	T1,(J)
	JRST	TTYRSB
	JUMPN	P1,TTYRSC
	SETZB	T1,DEVSTS(F)
	DPB	T1,BYTCNT
TTYRSC:	MOVE	T1,[TTYATC,,ASSCON]
	TDNN	T1,DEVMOD(F)
	PUSHJ	P,TTYKIL
TTYRSB:	HLRZ	F,DEVSER(F)
	MOVE	T1,DEVMOD(F)
	TLNE	T1,DVTTY
	JRST	TTYRSA
	HRRZ	F,TTYTAB##(J)	;GET CONTROLLING DDB ADDRESS
	JUMPE	F,CPOPJ##	;REALLY HAS TO BE ONE
TTYRS1:	MOVE	S,[IOLBKA,,IOSBKA!IOSTEC!IOSFCS+D] ;GET BITS

;THE FOLLOWING CHECK FOR NOT LOGGED IN, RUNNING "LOGIN"
; IS TO AVOID BREAKING ANCIENT "FEATURE" OF NOECHO GETTING
; SET BY LOGIN COMMAND.

	HRRZ	U,DDBLDB(F)	;LINK TO LDB
	JUMPE	U,TTYRS2	;NOT BATCH IS DETACHED
	PUSHJ	P,PTBTCH##
	  JRST	TTYRS2
	MOVE	T1,JBTSTS##(J)	;GET THIS STATUS
	MOVE	T2,JBTPRG##(J)	; AND PROGRAM NAME
	TLNN	T1,JLOG		;IS HE NOT LOGGED IN?
	CAME	T2,[SIXBIT/LOGIN/] ; AND RUNNING LOGIN
TTYRS2:	IORI	S,IOSNEC	;NOT BOTH, WE CAN CLEAR NOECHO
	ANDCAB	S,DEVIOS(F)	;CLEAR THESE BITS ON RESET
	JUMPE	U,CPOPJ##	;SKIP IT IF DETACHED
	MOVEI	T1,0		;CLEAR THE AUTO
	DPB	T1,LDPACR	;CRLF COUNTER
	PUSHJ	P,CLRIM1	;CLEAR IMAGE MODE
	MOVSI	T1,LDLBKA	;THE BREAK-ON-ALL-CHARACTERS BIT
	ANDCAM	T1,LDBDCH(U)	;CLEAR IN LDB SINCE TTYUSR ALREADY CALLED
				; AND WILL HAVE SET IT IF IOLBKA WAS SET
	PUSHJ	P,UUOLDB	;AND MAKE LDB AGREE
	PJRST	SETCHP		;FORCE CHANGE OF CHARACTERISTICS
;SUBROUTINE TO RETURN ONE CHARACTER FROM THE INPUT BUFFER. CHARACTER
;RETURNED IN T3.

COMTYI::PUSH	P,T2		;SAVE AC FOR OUTSIDE WORLD
	PUSHJ	P,CTIGLC	;GET THE LAST CHARACTER
	SKIPN	T3		;IS ANYTHING THERE FROM BEFORE?
	MOVEI	T3,12		;NO. ASSUME END OF LINE
	PUSHJ	P,SPCHEK	;YES. WAS IT A BREAK?
	  JFCL
	TLNN	T1,CHBRK	; ..
COMTI1:	PUSHJ	P,CTIGNC	;NO. GET ANOTHER CHARACTER (CCTYI OR ONCE)
	ANDI	T3,177		;COMCON DOESN'T WANT PARITY
	PUSHJ	P,SPCHEK	;CONVERT TO CONSISTENT BREAKS
	  JFCL			;ORDINARY CHARACTER
	TLNE	T1,CHCRET	;CARRIAGE RETURN?
	JRST	COMTI1		;YES. GO GET LINEFEED INSTEAD
	TLNE	T1,CHBRK	;BREAK?
	MOVEI	T3,12		;YES--MAKE INTO LINE FEED
	TLNE	T1,CHCNC	;IS THIS A CONTROL-C?
	MOVEI	T3,3		;YES--CONTROL-C IS STRONGER THAN LF
	PUSHJ	P,CTISLC	;SAY THAT THIS IS THE "LAST CHAR"
COMTIX:	PJRST	T2POPJ##	;RESTORE AC T2 AND RETURN


;SUBROUTINE TO SEND 1 CHAR, SENDING CONTROL CHARS AS ↑X
;OTHERWISE, SAME AS COMTYO

USEARO::PUSHJ	P,SPCHEK	;SPECIAL CHAR?
	  JRST	COMTYO		;NO, FORGET IT
	TLNN	T1,CHUAE	;ECHO AS ↑X?
	  JRST	COMTYO		;NO, GO ECHO NORMALLY
	PUSH	P,T3		;SAVE THE CHAR
	MOVEI	T3,336		;GET AN ARROW
	PUSHJ	P,COMTYO	;SEND IT
	POP	P,T3		;RESTORE CHAR
	TRC	T3,300		;CONVERT TO LETTER
;;	JRST	COMTYO		;AND GO TYPE IT


;SUBROUTINE TO SEND 1 CHARACTER, CHARACTER IN T3.
;PRESERVES T2 & T3

COMTYO::PUSH	P,T2		;SAVE AC
	PUSH	P,T3
	ANDI	T3,177		;SAVE PUSHJ TO PEVEN8, DO IT HERE
	MOVSI	T2,CHEPAR	;GET PARITY BIT
	TDNN	T2,CHTABL(T3)	;IS CHARACTER ALREADY EVEN PARITY?
	TRO	T3,200		;NO, MAKE IT SO
	PUSHJ	P,@.CPTOA##	;CALL  CCTYO, CTYWAT, OR ONCE ROUTINE
	POP	P,T3		;RESTORE
	JRST	T2POPJ##	; AC'S AND RETURN
;ROUTINE TO SWITCH TERMINAL TO USER PROGRAM LEVEL AND START USER RUNNING

TTYUSW::TDZA	S,S		;DON'T CLEAR WAIT BITS
TTYUSR::MOVE	S,[XWD IOW,IOACT]	;CLEAR WAIT BITS
	HRRZ	F,LDBDDB(U)	;GET ATTACHED DDB IF ANY
	JUMPE	F,TTYUS1	;JUMP IF NOT ATTACHED
	ANDCAB	S,DEVIOS(F)	; ..
	MOVSI	T1,LDLBKA	;THE VOLATILE BREAK-ON-ALL BIT
	TLNE	S,IOLBKA	;NEED TO RE-SET IT IN LDB?
	IORM	T1,LDBDCH(U)	;YES
	MOVSI	S,IOLBKA	;NOW CLEAR OUT
	ANDCAB	S,DEVIOS(F)	; ANNOYING TEMP BIT
	PUSHJ	P,UUOLDB	;MAKE LINE AND DEVIOS AGREE
TTYUS1:	MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNE	T1,LDRPTY	;IS THIS A PTY?
	PUSHJ	P,PTMNMZ##	;YES. TELL CONTROLLER
	MOVSI	T1,LDLCOM	;PUT TERMINAL IN USER MODE
	ANDCAM	T1,LDBDCH(U)	;MAY BE DETACHED, BUT WILL WAIT
				; AT UUO LEVEL IF NEEDED
	PJRST	SETRUN##	;SET USER'S RUN BIT AND RETURN



TTYSTC::HLL	U,LDBDCH(U)	;SEE IF THIS LINE IS SLAVED
	MOVSI	T1,LDLCOM	;PREPARE TO SET BIT
	TLNN	U,LDLSLV	;SLAVED?
IFN FTMIC,<			;IF MIC
	IORM	T1,LDBDCH(U)	;NO. SET COMMAND BIT
	PUSHJ	P,MICWAK	;WAKE MIC IF NECESSARY
> ;END OF IF MIC
IFE FTMIC,<IORB T1,LDBDCH(U)>	;NO, SET COMMAND BIT
	TRNE	T1,LDRPTY	;PTY-DRIVEN LINE?
	PUSHJ	P,PTMNMD##	;YES. TELL CONTROLLER
TTYSTR::MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNE	T1,LDRPTY	;IS IT A PTY?
	PUSHJ	P,PTYPE##	;YES. WAKE THE PTY CONTROLLER
	PUSHJ	P,COMQ		;AT COMMAND LEVEL?
	  PJRST NOCTRO		;NO. JUST CLEAR ↑O BIT
	PUSHJ	P,TYIEAT	;YES. CLEAR THE COMMAND IN CASE MORE
	PUSHJ	P,STRTDL	;ECHO ONE DEFERRED LINE IF NECESSARY
	SKIPLE	LDBBKC(U)	;ANY MORE COMMANDS?
	PUSHJ	P,COMSET	;MAYBE. SET BIT IF AT COM LEVEL
	PJRST	NOCTRO		;CLEAR OSU AND RETURN
;HERE AT COMPLETION OF A COMMAND

TTYCMR::PUSH	P,T1		;SAVE PREVIOUS LDPCMX
	TRNN	F,-1		;ANY JOB?
	PUSHJ	P,TTYCPT	;NO. CLEAR PAPER-TAPE BITS
	AOS	T1,LINSAV##
	CAIL	T1,TTPLEN##
	SETZM	LINSAV##
	HLL	T2,LDBDDB(U)	;GET COMMAND REQUEST BITS
	POP	P,T1		;COMMAND JUST FINISHED
	LDB	T3,LDPCMX	;CURRENT
	CAME	T1,T3		;CHANGED?
	TLNN	T2,LDBCMF	;FORCED
	SKIPA			;NO CHANGE OR NOT FORCED
	POPJ	P,		;NEW FORCED-DO IT
	MOVEI	T1,L2RECS	;SET EAT-COMMAND-SYNC BIT
	TLNN	T2,LDBCMF	;(UNLESS FORCED COMMAND)
	IORM	T1,LDBBY2(U)	;IN LINE DATA BLOCK
	MOVSI	T1,LDBCMR+LDBCMF;CLEAR COMMAND REQUEST BITS
	ANDCAB	T1,LDBDDB(U)	;IN BASE WORD OF LDB
	MOVE	T1,LDBDCH(U)	;GET THE LINE'S CHARACTERISTIC
	TLNN	T1,LDLBKA+LDLIMI;ARE WE BREAKING ON ALL CHARACTERS
				; OR IN IMAGE MODE?
	JRST	TTCMR1		;NO, CONTINUE ON
	SKIPLE	LDBTIC(U)	;YES, DO WE HAVE ANY CHARACTERS
				; IN THE INPUT BUFFER?
	PUSHJ	P,RCVWAK	;YES, WAKE THE JOB
				;NO,...
TTCMR1::MOVE	T1,LDBDDB(U)	;GET THE LINES LDBDDB & CONTINUE
	TLNN	T1,LDBCMK	;FORCED KJOB PENDING?
IFN FTMIC,<			;IF MIC
	PUSHJ	P,CMDCLR	;NO, CLEAR COMMAND BIT
	PJRST	MICWAK		;WAKE MIC UP IF NEC & RETURN TO COMCON
> ;END OF IF MIC
IFE FTMIC,<			;IF NOT MIC
	PJRST	CMDCLR		;NO, CLEAR COMMAND BIT
	POPJ	P,0		;YES, DO NOT CLEAR COMMAND BIT
> ;END OF IF NOT MIC
	SUBTTL	SUBROUTINES FOR COMCON OR UUO LEVEL

;COMMON UUO LEVEL ROUTINES
;TYO7W IS USED TO TAKE A 7-BIT CHARACTER IN T3
; GO INTO I/O WAIT IF JOB DETACHED OR IF THE LINE'S
; OUTPUT BUFFER IS RATHER BIG, THEN PLACE THE CHARACTER IN OUTPUT
; STREAM, AND START OUTPUT IF NEEDED.
;TYO9W IS SAME, BUT ASSUMES PARITY AND NINTH BIT ARE AS DESIRED.
;TYO CHOOSES ONE OF THE ABOVE, DEPENDING ON MODE IN S
;CALL TYO9W WITH SIGN BIT OF T3 SET TO AVOID BLOCKING
; (USED TO AVOID WTP STOPED ON CALL FROM TTMORE)
;CALL WITH DDB SET UP, CHARACTER IN T3.
;IF CALLED AT TYO, S MUST BE SET UP ALSO

TYO:	TRNN	S,I!PIMMOD	;IMAGE MODE USE OWN PARITY
TYO7W:	ANDI	T3,177

;(110) NEW TELNET (APR 74) ALLOWS 8-BIT TRANSFERS, BUT WILL USE 377 AS A
;(110)  TELNET COMMAND. TO AVOID CONFUSION, WE MUST QUOTE IT HERE. (IT COULD
;(110)  ALSO BE DONE IN IMPSER.)

TYO9W:	MOVE	S,DEVIOS(F)
	TRNE	S,IODERR	;↑C TYPED ON TTYNNN
	POPJ	P,		;YES, DON'T OUTPUT CHR
	PUSHJ	P,CKATTO	;WAIT FOR ATTACH, SET LINE.
IFN FTCIMP,<
	MOVEI	T1,LDRIMP	;(110) SET UP FOR ITY CHECK
	CAIN	T3,377		;(110) ONLY WORRY ABOUT IMAGE RUBOUT
	TDNN	T1,LDBDCH(U)	;(110) AND ONLY IF GOING TO ITY
	PJRST	TYO9C1		;(110) NO PROBLEM
	PUSHJ	P,TYO9C1	;(110) SEND IT DOWN THE FIRST TIME
	MOVEI	T3,377		;(110) ONCE MORE
TYO9CH:	PUSHJ	P,CKATTO	;(110)
TYO9C1:				;(110)
> ;(110) END IFN FTCIMP

	MOVE	T1,TTFREN##	;MAKE SURE THERE'S SOME CHARACTER SPACE LEFT
	CAIGE	T1,3		;LEAVE 3 CHUNKS FOR SAFETY
	JRST	TYONFC		;NO, GO INTO I/O WAIT UNTIL SOME FREE
	MOVE	T1,LDBTOC(U)	;GET OUTPUT STREAM LENGTH
	CAML	T1,TIWRNN	;IS HE OVER QUOTA?
	JUMPGE	T3,TYOOBF	;YES. WAIT FOR IT TO EMPTY.
IFN FTMIC,<
IFN FTMLOG,<
	SKIPN	LDBLOT(U)	;IS HE LOGGING
	JRST	TYO9M		;NO
	ADD	T1,LDBLOC(U)
	CAIL	T1,↑D100
	JRST	MICLGX		;GO WAKE UP MIC
TYO9M:>	;END OF FTMLOG CONDITIONAL
>;END IFN FTMIC
	MOVE	T1,LDBDCH(U)	;CHECK FOR OUTPUT SUPPRESS
	SKIPL	LDBOFL(U)
	TRNE	T1,LDROSU	; ..
	POPJ	P,0		;NO. JUST RETURN DUE TO ↑O
TYO9A:				;(110)
IFN FTLINK,<			;(111)
	PUSHJ	P,CHKLNK##	;(111) SEND CHAR (COMCON/UUO LEVEL) TO ANY LINKS
LnkCpy::	; entry to avoid LnkSer recursion.
>;(111)
	SCNOFF			;NO RACES
	STCHK	T3,LDBTOP(U)	;STORE CHARACTER IN CHUNKS
	AOS	LDBTOC(U)	;COUNT UP OUTPUT STREAM LENGTH
	SCNON			;ALLOW INTERRUPTS
IFN FTMIC,<			;IF MIC
	PUSHJ	P,MICPOS	;YES SET UP AND CHECK POSITION
> ;END OF IF MIC
	PJRST	TOPOKE		;START OUTPUT FOR THE LINE
TYOVRG:	SCNOFF			;NO INTERRUPTS
	pushj	p,tyovri	; call no interrupt version
	JRST	SONPPJ		;REENABLE INTERRUPTS AND RETURN

; enter here with interrupts already off if we need to avoid
;  a race at entry.
tyovri::SKIPE	T1,LDBTOT(U)	;IF ALREADY A GOOD POINTER
	JRST	TYOVR1		;DON'T WASTE A GOOD CHUNK
	PUSHJ	P,GETCKZ	;GET A CHUNK FROM FREELIST
	ADD	T1,[POINT 9,1]	;MAKE INTO A BYTE POINTER
	MOVEM	T1,LDBTOT(U)
TYOVR1:	MOVEM	T1,LDBTOP(U)	;PUT IN TYPEOUT STRING ADDRESSES
	SETZM	LDBTOC(U)	;MAKE SURE COUNT IS ZERO
	popj	p,		; return


;HERE IF NO FREE CHUNKS
TYONFC:	PUSH	P,16		;ACS USED BY SETSLP
	PUSH	P,17
	PUSH	P,T3
	PUSH	P,U
	MOVEI	T1,5		;SLEEP FOR 5 SEC.
	PUSHJ	P,SLEEP##	; ..
	POP	P,U		;RESTORE AC(S
	HRRZ	F,LDBDDB(U)
	POP	P,T3
	POP	P,17
	POP	P,16
IFE FTCIMP,<			;(110)
	JRST	TYO9W
>;(110)
IFN FTCIMP,<			;(110)
	JRST	TYO9CH		;(110)
>;(110)


IFN FTMIC&FTMLOG,<
MICLGX:	PUSHJ	P,MICWAK
	JUMPL	T3,TYO9M		;DON'T BLOCK IF FROM TTMORE
> ;END OF FTMLOG CONDITIONAL

;HERE IF OUTPUT BUFFER FULL
TYOOBF:	PUSHJ	P,TOWAT1
IFE FTCIMP,<			;(110)
	JRST	TYO9W
>;(110)
IFN FTCIMP,<			;(110)
	JRST	TYO9CH		;(110)
>;(110)

;SUBROUTINE TO SETUP A BYTE COUNT AND POINTER TO A USER'S BUFFER
;CALLING SEQUENCE:
;	MOVE	S,DEVIOS(F)
;	HRRZ	P1,USER VIRTUAL ADDRESS OF BUFFER
;	PUSHJ	P,SRLPTR
;
;ON RETURN P1 IS A BYTE POINTER TO THE USER BUFFER AND P2 IS THE MAXIMUM
;BYTE COUNT FOR THE BUFFER.

SRLPTR:	ADD	P1,[POINT 7,2]	;ASSUME ASCII MODE (AND SKIP .BFCNT WORD)
	TRNE	S,PIMMOD	;PACKED IMAGE MODE?
	HRLI	P1,(POINT 8,)	;YES, USE 8-BIT BYTES
	TRNE	S,I		;REGULAR IMAGE MODE?
	HRLI	P1,(POINT 36,)	;YES, USE 36-BIT BYTES
	TRNN	S,I!PIMMOD	;ASCII MODE?
	IMULI	P2,5		;YES, 5 BYTES PER WORD
	TRNE	S,PIMMOD	;PACKED IMAGE MODE?
	IMULI	P2,4		;YES, 4 BYTES PER WORD
	POPJ	P,
;SUBROUTINE FOR COMMAND LEVEL OUTPUT


CCTYO::	JUMPE	U,CPOPJ##	;U MUST BE SET UP
IFN FTCIMP,<			;(110)
	ANDI	T3,177		;(110) COMPUTE PARITY HERE SINCE IMPSER CALLS
CCTYO9::			;(110) THIS ROUTINE TO OUTPUT TELNET CODES
>;(110)
	MOVE	T1,LDBTOC(U)	;GET COUNT
	SUBI	T1,↑D200
	SKIPLE	T2,TTFREN##	;SPACE IN STRINGS?
	CAML	T1,TIWRNN	;YES. SPACE IN THIS GUY'S AREA?
	POPJ	P,0		;NO. QUIT.
	CAIL	T2,3
	SKIPN	TTFTAK		;IS THERE A FREE LIST?
	POPJ	P,		;NO--PUNT
IFE FTCIMP,<			;(110)
	ANDI	T3,177		;FORCE EVEN PARITY SINCE CCTYO NEVER DOES IMAGE
>;(110)
	JRST	TYO9A		;YES. GO TYPE IT.

	$LOW			;MUST BE IN THE LOW SEGMENT FOR ONCE-ONLY
;SUBROUTINE TO PRINT ON CTY IN EMERGENCY OR ONCE-ONLY
; WHEN INTERRUPT SYSTEM CANNOT BE USED OR TRUSTED
;CALL:	MOVEI	T1,ADR OF ASCIZ MESSAGE
;	PUSHJ	P,CTYTYP
;	ALWAYS	RETURN

CTYTYP::HRLI	T1,440700	;FORM BYTE POINTER
CTYTYL:	ILDB	T3,T1		;GET NEXT CHARACTER
	JUMPE	T3,LCPOPJ	;END OF MESSAGE?
				;(CPOPJ IS IN HISEG, SO DON'T USE IT)
	PUSHJ	P,CTYWAT	;NO, PRINT IT ON CTY AND WAIT
	JRST	CTYTYL		;GO GET NEXT CHAR.



;ROUTINE RESIDING IN LOSEG TO COMPUTE PARITY.
; USED ONLY FOR EMERGENCY CTY OUTPUT ROUTINES.
; USES T1

CTYPAR:	MOVEI	T1,(T3)
	LSH	T1,-4		;FOLD INTO LOW 4 BITS
	XORI	T1,(T3)
	TRCE	T1,14		;CHECK BITS 32 AND 33
	TRNN	T1,14
	TRC	T3,200		;IF EVEN PARITY COMPLEMENT RESULTS
	TRCE	T1,3
	TRNN	T1,3
	TRC	T3,200		;IF EVEN PARITY COMPLEMENT RESULTS
	POPJ	P,		;RETURN
;SUBROUTINE FOR ERROR MESSAGE TO CTY DURING PARITY ERROR STOP
;CALL:	MOVEI	T3,CHARACTER
;	PUSHJ	P,CTYWAT
;	RETURN AFTER CHARACTER HAS BEEN TYPED
;NOTE:  DOES NOT USE INTERRUPT SYSTEM SO MESSAGE WILL GET OUT BEFORE HALT
;THIS SUB CALLED BY COMTYO WHEN COMTOA PATCHED

CTYWAT::PUSH	P,T1
	PUSHJ	P,CTYPAR	;COMPUTE PARITY WITH LOSEG ROUTINE

IFN FTKI10,<
	CONSZ	CTY,20		;WAIT FOR CTY TO BE IDLE
	JRST	.-1		;NO, SO NOT GARBLE ON GOING OUTPUT
	DATAO	CTY,T3		;YES, SEND OUT CHAR
	PUSHJ	P,OPRFIL
	CONSZ	CTY,20		;WAIT FOR CTY TO BE IDLE
	JRST	.-1		;NO, OTHERWISE HALT OR RESET WILL CLOBBER LAST CHAR
	JRST	OPRFI2		;YES, OK TO RETURN
>;END FTKI10

IFN FTKS10,<
	SKIPE	CTYOWD		;CAN WE TYPE YET ?
	JRST	.-1		;WAIT A WHILE
	TRO	T3,CTYOVL	;VALID FLAG
	MOVEM	T3,CTYOWD	;PUT UP FOR FRONT END TO SEE IT
	RDAPR	T1		;GET PROCESSOR PIA
	ANDI	T1,SP.PIA	;LEAVE ONLY THE PIA
	WRAPR	SP.SSF+SP.IFE(T1) ;INTERRUPT THE FRONTEND
	SKIPE	CTYOWD		;WAIT FOR CTY TO BE IDLE
	JRST	.-1		;OTHERWISE HALT OR RESET WILL CLOBBER LAST CHAR
	JRST	OPRFI2		;OK TO RETURN
>;IFN FTKS10

IFN FTKL10,<
	PUSHJ	P,SPCTYO##	;SEND CHAR OVER
	PUSHJ	P,SPCWTO##	;WAIT FOR OUTPUT TO COMPLETE
	  JRST	.-1
	JRST	OPRFI2		;RESTORE T1
				;AND RETURN
>;END IFN FTKL10
	$HIGH			;BACK TO THE HIGH SEGMENT
;SUBROUTINE TO CLEAR PAPER TAPE INPUT BITS, RETURNS LDBDCH IN T1
TTYCPT::MOVSI	T1,L2LTAP	;CLEAR TTY TAPE COMMAND BIT
	ANDCAM	T1,LDBBY2(U)	;IN BY2
	MOVEI	T1,L2RXON	;CLEAR XON IN EFFECT
	ANDCAB	T1,LDBBY2(U)	;AND RETURN NEW STATUS
	POPJ	P,		;RETURN

	$LOW			;MUST BE IN THE LOW SEG FOR EMERGENCIES

;SUBROUTINE TO ADD A DELAY FOR SLOW CTY'S
;CALL WITH:
;	MOVEI	T3,CHAR
;	PUSHJ	P,OPRFIL
;USED ONLY WITH PI SYSTEM OFF
OPRFIL::ANDI	T3,177		;ONLY CHAR BITS
	PUSH	P,T1		;SAVE T1
	MOVEI	T1,0		;ASSUME NO FILLERS
	CAIN	T3,12		;LF GETS
	MOVEI	T1,CTYDLF##	;8 TICKS
	CAIN	T3,15		;CR GETS
	MOVEI	T1,CTYDCR##	;18 TICKS
	JUMPE	T1,OPRFI2	;RETURN
	ADDM	T1,TIME##	;UPDATE TIME
IFN FTKI10,<
OPRFI1:	CONSO	APR,XP.CLK	;DID CLOCK TICK?
	JRST	OPRFI1		;NO -- WAIT FOR IT
	CONO	APR,XP.CCF	;CLEAR CLOCK FLAG
>;END IFN FTKI10

IFN FTKS10,<
OPRFI1:	RDAPR	T1		;GET CLOCK FLAG
	TRNN	T1,SP.ITI	;DID CLOCK TICK ?
	JRST	OPRFI1		;NOT YET
	WRAPR	SP.CSF+SP.ITI	;CLEAR CLOCK FLAG
>;IFN FTKS10

IFN FTKL10,<
OPRFI1:	CONSO	TIM,TI.ITD	;CLOCK "TICK" ?
	JRST	OPRFI1		;NOT YET
	CONO	TIM,@ONCKLT##	;YES, CLEAR AND SET FOR ANOTHER "TICK"
>;END IFN FTKL10
	SOJG	T1,OPRFI1	;LOOP FOR WHOLE TIME
OPRFI2:	POP	P,T1		;--
LCPOPJ:	POPJ	P,		;LOCAL CPOPJ FOR USE WHEN HISEG ISN'T MAPPED
	$HIGH			;BACK TO THE HIGH SEGMENT
;ROUTINE TO FIND A FREE TTY DEVICE DATA BLOCK

;CALL FROM CLOCK LEVEL TO DO AN ATTACH ON A NEW JOB, OR
;FROM UUO LEVEL ON AN INIT OF A NEW LINE.

;CALL:	NO ARGUMENTS
;	PUSHJ P,DDBSRC
;	  ERROR RETURN		;NONE AVAILABLE. F=0. T1 CLOBBERED
;	OK RETURN		;ADDRESS IN F, TTYUSE SET IN DEVMOD
;				;RESPECTS J,U,T2.
;				;IF YOU DECIDE NOT TO USE DDB, YOU BETTER
;				;FREE IT UP AGAIN.


DDBSRC:	PUSHJ	P,DDBSR0	;TRY TO GET A DDB
	  SKIPA			;LOST -- TRY AGAIN
	PJRST	CPOPJ1##	;WE WON
DDBSR0:	MOVEI	F,TTYLST	;START OF THE TTY DDB'S
DDBSRA:	MOVSI	T1,TTYUSE	;FLAG THAT A DDB ISN'T FREE
	SCNOFF			;MAKE SURE NO CONFLICT HERE
	TDNN	T1,DEVMOD(F)	;IS THIS DDB FREE?
	JRST	DDBSR1		;YES. GO GRAB IT.
	SCNON			;NO. REENABLE PI SYSTEM
	HLRZ	F,DEVSER(F)	;LINK DOWN THE DDB CHAIN
	MOVE	T1,DEVMOD(F)	;MAKE SURE STILL A TTY DDB
	TLNE	T1,DVTTY	;IS IT?
	JUMPN	F,DDBSRA	;YES. (UNLESS END OF CHAIN)
	MOVEI	F,0		;NO MORE TTY DDB'S. WE LOSE.
	POPJ	P,0		;RETURN NON-SKIP, WITH 0 IN DDB

DDBSR1:	IORM	T1,DEVMOD(F)	;SET BIT SO WE HAVE THE DDB
	SCNON			;NOW PI'S CAN HAPPEN AGAIN
	PUSHJ	P,CLRDVL##	;CLEAR JOB NO. IN CASE OF JUNK
	MOVE	T1,[XWD TTYATC,ASSCON+ASSPRG]	;LIKEWISE MODE BITS
	ANDCAM	T1,DEVMOD(F)	; ..
	SETZM	DEVLOG(F)	;AND LOGICAL NAME
	MOVSI	T1,IOFST	;AND INITIAL S WORD
	MOVEM	T1,DEVIOS(F)	;WHICH SHOULD LEAVE IT PRETTY CLEAN
	JRST	CPOPJ1##	;SKIP RETURN. WE HAVE A DDB.

;ROUTINE TO FIND A TTY DDB WHICH IS ATTACHED TO, I.E.
;CONTROLLING, A PARTICULAR JOB NUMBER.
;
;CALLED AT COMMAND LEVEL BY ATTACH COMMAND, AND AT UUO LEVEL
;BY REFERENCES TO DEVICE "TTY" OR TTCALLS, ETC.
;
;CALL:	MOVE J,JOB NUMBER DESIRED
;	PUSHJ P,TTYSRC
;	  ERROR RETURN.	;NOT FOUND. AC'S U,F,S NOT GUARANTEED
;	NORMAL RETURN	;U, S AND F SET UP. NOTE THAT THIS DOES
;			;!NOT! IMPLY THAT ANYONE IS ATTACHED. THAT IS,
;			; U MAY CONTAIN A ZERO
;
;			;CLOBBERS T1

TTYSRC::JUMPLE	J,CPOPJ##	;NOBODY CONTROLS JOB ZERO. YOU ARE CONFUSED.
	HRRZ	F,TTYTAB##(J)	;GET CONTROLLING TTY DDB ADDRESS
	JUMPE	F,CPOPJ##	;RETURN IF NONE
	MOVE	T1,DEVMOD(F)	;GET DEVICE BITS FROM DDB
	TLNN	T1,TTYATC	;IS THIS THE CONTROLLING TTY?
	POPJ	P,0		;NO. IT WAS A SLAVE OR SOMETHING.
	HRRZ	U,DDBLDB(F)	;YES. GET THE LDB LINK (MAY BE 0)
	MOVE	S,DEVIOS(F)	;AND I/O STATUS WORD
	JRST	CPOPJ1##	;GIVE SUCCESS RETURN.
;ROUTINE CALLED WHEN DEVSRC CAN'T FIND DEVICE XXX (IN T1), AND
; IT WANTS TO SEE IF IT IS A PHYSICAL TTY. GETDDB CHECKS NAME,
; AND IF IT SHOULD BE A TTY, LOOKS FOR ITS DDB, OR MAKES ONE.
;
;CALL:	MOVE J,JOBNUMBER
;	MOVE T1,SIXBIT DEVICE NAME, ALLEGEDLY A PHYSICAL TTY NAME
;	PUSHJ P,GETDDB
;	  ERROR RETURN, NOT A TTY OR THERE ARE NO DDB'S AVAILABLE.
;	OK RETURN. IT IS A TTY, AND F AND U ARE NOW SET TO IT.
;RESPECTS T1 ON THE OK RETURN ONLY
;
;CALLED FROM DEVSRC, SO MAY BE AT UUO OR CLOCK LEVEL

GETDDB::
IFN FTMP,<
	PUSHJ	P,INTLVL##	;IF AT UUO LEVEL
	  PUSHJ	P,ONCPU0##	;AVOID RACES WITH COMCON
>
	PUSHJ	P,TTYPHY	;LOOK FOR THIS PHYSICAL NAME
	  POPJ	P,0		;IT ISNT A TTY
	JUMPN	F,GETDB5	;IS THERE A DDB ALREADY?
				;IF SO, SOMEONE HAS CALLED GETDDB WHO
				; COULD HAVE CALLED DEVSRC.
	PUSHJ	P,CHKFLN	;CHECK FOR LEGAL ACCESS TO FRCLIN
	PUSHJ	P,DDBSRC	;NO. NEED A NEW DDB. TRY TO GET ONE.
	  POPJ	P,0		;NONE AVAILABLE. FAIL RETURN
	HRRM	F,LDBDDB(U)	;SUCCESS. SET LINKS TO AND FROM DDB
	HRRM	U,DDBLDB(F)	; AND LINE DATA BLOCK.
	PUSHJ	P,SCNNAM	;FILL IN REAL NAME AND PUNIT
IFN FTNET,<PUSHJ P,SETSTA>	;PUT STA # IN DDB
GETDB5:	MOVE	T1,DEVNAM(F)	;RESTORE REAL NAME TO T1
	JRST	CPOPJ1##	;AND GIVE SUCCESSFUL RETURN FROM GETDDB


;ROUTINE TO CHECK FOR LEGAL ACCESS TO FRCLIN.
;CALL:	MOVE	U,LDB ADDRESS
;	PUSHJ	P,CHKFLN
;	  RETURN HERE IF NOT FRCLIN OR LEGAL ACCESS
;	  RETURN HERE IF ACCESS NOT LEGAL
;DESTROYS T1

CHKFLN:	LDB	T1,LDPLNO	;GET LINE NUMBER
	CAIE	T1,FRCLIN##	;IS IT FRCLIN?
	POPJ	P,		;NO, GIVE OK RETURN
	PUSHJ	P,SAVT##	;SAVE T1-T4 FOR SAFETY
	MOVSI	T1,JP.POK	;MUST HAVE POKE PRIVILEGE OR BE
	PJRST	PRVBIT##	;BE LOGGED INTO [1,2] OR JACCT
;SUBROUTINE TO PUT PHYSICAL NAME INTO T2 FOR U WHOSE LDB IS IN U
;EVEN THOUGH THERE MAY BE NOTHING IN F OR LDBDDB

TTYNAM::PUSH	P,[SIXBIT /CTY/];SEE IF CTY
	MOVEI	T1,LDRCTY
	TDNE	T1,LDBDCH(U)
	JRST	T2POPJ##	;YES.
	LDB	T1,LDPLNO
	MOVSI	T3,'TTY'	;NO. CHANGE TO TTY
	MOVEM	T3,0(P)		;ON STACK
	MOVSI	T3,(POINT 6,0,17) ;SETUP SIXBIT BYTE POINTER TO
	HRRI	T3,0(P)		;NAME ON THE STACK
	PUSHJ	P,SCNNMR	;AND CALL SAME ROUTINE AS SCNNAM DOES
	PJRST	T2POPJ##	;PUT ANSWER IN T2
				;AND RETURN FROM TTYNAM
;SUBROUTINE TO FIND LDB FOR A PHYSICAL NAME, IF ITS A TTY
;AND LOAD F WITH LINKED DATA BLOCK, IF ANY, BUT DON'T MAKE ONE IF NONE YET
;SKIP RETURN IF ITS A TTY


TTYPHX:	PUSHJ	P,TSTOPR##	;SEE IF OPR AND FUDGE T1
	PUSHJ	P,SAVE2##
	PUSH	P,T1		;SAVE NAME
	MOVE	P1,BOOTCT##
	CAMN	T1,[SIXBIT /CTY/] ;IS CTY WANTED?
	JRST	TTYPH1		;YES. GO USE TCONLN
	HLLZ	P1,T1		;GET FIRST THREE CHARACTERS
	CAMN	P1,[SIXBIT /TTY/] ;ARE THEY TTY?
	TRNN	T1,770000	;AND ALSO IS FOURTH CHAR NON-BLANK?
	PJRST	TPOPJ##		;NO. NOT A LEGAL NAME.
	MOVSI	P2,(<POINT 6,0(P),17>)	;POINTER TO READ CHARS
	MOVEI	P1,0		;INITIALIZE LINE TO 0
TTYPH4:	ILDB	T1,P2		;GET A SIXBIT CHARACTER FROM NAME
	JUMPE	T1,TTYPH2	;JUMP IF END OF NAME.
	TRC	T1,"0"-40	;CONVERT SIXBIT TO BINARY
	CAILE	T1,7		;IS IT AN OCTAL DIGIT?
	JRST	TPOPJ##		;NO. BAD CHAR IN NAME
	ASH	P1,3		;MULTIPLY BY 8
	ADDI	P1,0(T1)	;ADD IN THIS DIGIT
	TLNE	P2,770000	;CHECK FOR MORE DIGITS
	JRST	TTYPH4		;LOOP FOR MORE DIGITS
TTYPH2:	CAMLE	P1,P3		;IS IT A LEGAL HARDWARE LINE #?
	JRST	TPOPJ##		;NO. TOO BAD.
TTYPH1:	HRRZ	U,LINTAB##(P1)	;GET LINE DATA BLOCK ADDRESS
	HRRZ	F,LDBDDB(U)	;GET ATTACHED DDB, IF ANY.
	JRST	TPOPJ1##	;GOOD RETURN

TTYPHY::PUSH	P,P3		;SET UP FOR PHYSICAL ONLY
	MOVEI	P3,TCONLN##
TTYPHZ:	PUSHJ	P,TTYPHX	;CALL COMMON SUBROUTINE
	  SOS	-1(P)		;REMEMBER NON-SKIP RETURN
	POP	P,P3		;BY PROPAGATING IT
	JRST	CPOPJ1##

TTYALL::PUSH	P,P3		;TRY ALLL-PHYSICAL & VIRTUAL
	MOVEI	P3,TTPLEN##
	JRST	TTYPHZ
;SUBROUTINE TO FIND TTY FOR A JOB IN J (TTYFND) OR FOR
; CURRENT JOB (TTYFNU)
;RETURN WITH F AND U SET UP.
;GOES TO ERROR IF NO TTYDDB FOR THE JOB.


TTYFNU::MOVE	J,.CPJOB##	;GET CURRENT UUO LEVEL JOB NUMBER
TTYFND::PUSHJ	P,TTYSRC	;FIND THE JOB'S TTY DDB, ALSO U AND S
	  STOPCD CPOPJ##,DEBUG,NDJ,	;++NO DDB FOR JOB
TTYFNX:	POPJ	P,0		;SUCCESS. RETURN.

;SUBROUTINE TTYFUW (TELETYPE FIND FOR CURRENT USER AND WAIT), TO
;FIND CURRENT USER'S TTY AND WAIT FOR IT TO COME OUT OF OUTPUT
;WAIT, AND BE ATTACHED.
;SUBROUTINE TOWAIT, TO WAIT FOR TYPEOUT ACTIVITY TO (NEARLY) COMPLETE,
;IF NECESSARY.


TTYFUW::PUSHJ	P,TTYFNU	;FIND USER'S TTY
	PUSHJ	P,CKATTO	;CHECK THAT IT'S ATTACH. WAIT IF NOT.
IFN FTMIC,<			;IF MIC
	MOVE	T1,LDBMIC(U)
	TLNE	T1,LDLRSP!LDLRSY
	POPJ	P,0		;IF HE WANTS RESPONSE STUFF DO NOT TO
> ;END OF IF MIC
;ROUTINE TO WAIT FOR NEARLY EMPTY OUTPUT BUFFER. CALL ONLY AT UUO LEVEL
TOWAIT:	MOVE	S,[XWD	TTYOUW+IO+IOW,IOACT]	;SET ACTIVE & WAITING FIRST TO AVOID COMPLETION
	IORM	S,DEVIOS(F)	;BETWEEN TEST FOR COMPLETION & IOACT SET
	MOVE	T1,LDBTOC(U)	;GET COUNT OF TYPE-OUT CHARACTERS WAITING.
	CAIL	T1,10		;OVER 7?
	JRST	TOWAT2		;YES. HAVE TO WAIT
	ANDCAB	S,DEVIOS(F)	;NO. NOT WAITING, SO TURN OFF BITS
	POPJ	P,		;& RETURN
TOWAT1:	MOVE	S,[XWD TTYOUW+IO,IOACT]	;FLAG OUTPUT WAIT ACTIVITY
TOWAT2:	IORB	S,DEVIOS(F)	;IN THE DEVICE DATA BLOCK
	PUSHJ	P,PTSTRT	;WAKE UP SUBJOB, IF ANY
	PUSHJ	P,WSYNC##	;WAIT FOR IO TO COMPLETE
	HRRZ	U,DDBLDB(F)	;SET UP LDB IN CASE DETACH/ATTACHAPPENED WHILE WAITING
	JUMPE	U,TTYFUW	;MAKE SURE TTY STILL ATTACHED
	POPJ	P,		;AND RETURN


PTSTRT:	JUMPE	U,CPOPJ##	;IN CASE U NOT SET UP
	MOVEI	T1,LDRPTY	;GET PTY BIT
	TDNE	T1,LDBDCH(U)	;IS THIS ONE
	PJRST	PTYPE##		;YES, WAKE UP CONTROLLER
	POPJ	P,		;NO, RETURN
;SUBROUTINE TTYERP TO FIND TTY DDB FOR A MONITOR ERROR MESSAGE.
;CALL WITH J SET TO JOB NUMBER TO BE TYPED AT.
;IF JOB IS ZERO, OR IF DESIRED JOB IS DETACHED, TTYERP RETURNS
;WITH U SET TO OPERATOR'S CONSOLE, AND F SET FROM IT,
;BUT OF COURSE THAT DDB MAY BE ZERO, SINCE MAY BE NO JOB AT OPR.


TTYERP::PUSHJ	P,TTYSRC	;FIND THE TTY DDB IF POSSIBLE
	  JRST TTYERO		;NONE THERE. MAYBE JOB 0. GO FIND OPR
	JUMPN	U,CPOPJ1##	;SKIP RETURN TO SIGNAL LDB FOUND
TTYERO:	SKIPN	U,OPRLDB##	;GET OPERATOR LINE FROM ONCE
	STOPCD	CPOPJ##,DEBUG,NOT,	;++NO OPR TTY
	HRRZ	F,LDBDDB(U)	;GET DDB ADR, IF ANY.
TTYERX:	POPJ	P,0		;AND RETURN FROM TTYERP


;SUBROUTINES TO SET UP LINE AND MAKE SURE ATTACHED.
;CALL WITH DDB SET UP, FROM UUO LEVEL ONLY.
;RETURN WHEN ATTACHED AND AT USER LEVEL, WITH LINE SET UP.

;ONE ROUTINE FOR INPUT, ONE FOR OUTPUT, ONE FOR OUTPUT AND USER LEVEL

CKATTI:
IFN FTRSP,<PUSHJ P,RSPTIR##>	;RECORD RESPONSE SATISFIED BY TTY INPUT UUO
CKATT0:	MOVSI	S,IO		;INDICATE INPUT
	ANDCAB	S,DEVIOS(F)	;SET UP STATUS WORD
	HRRZ	U,DDBLDB(F)	;GET LINE BLOCK ADDR
	JUMPN	U,CKATI1	;IF THERE, GO ON
CKATIW:	MOVSI	S,IO+TTYOUW	;MUST WAIT FOR ATTACH
	ANDCAM	S,DEVIOS(F)	;CLEAR DIRECTION BIT
	MOVEI	S,IOACT		;AND SET WAIT BIT FOR INPUT
	IORB	S,DEVIOS(F)	; ..
	PUSHJ	P,WSYNC##	;WAIT FOR ATTACH
	JRST	CKATT0		;GET LINE SET UP AND RETURN.

CKATI1:	MOVE	T1,DEVMOD(F)	;SEE IF TTY IS CONTROLLING JOB.
	TLNE	T1,TTYATC
	JRST	CKATI2		;YES.
	MOVSI	T1,LDLCOM	;NO. MAKE IT BE
	ANDCAM	T1,LDBDCH(U)	;AT USER LEVEL
CKATI2:	HLL	U,LDBDCH(U)	;GET DEVICE BITS
	TLNE	U,LDLCOM	;AT COMMAND LEVEL?
	JRST	CKATIW		;YES. CAN'T DO INPUT.
	PUSHJ	P,TYIEAT	;NO. SKIP ANY COMMANDS
	PJRST	UUOLDB		;AND GO ADJUST LINE BITS.

CKATOU:	PUSHJ	P,CKATTO	;FIRST MAKE SURE A LINE ATTACHED TO DDB
	TLNN	U,LDLCOM	;IS LINE AT COMMAND LEVEL?
	POPJ	P,0		;NO. USER LEVEL. RETURN.
	MOVE	T1,DEVMOD(F)	;COMMAND LEVEL.  SEE IF CONTROLLER OR I/O DEVICE
	TLNN	T1,TTYATC	;..
	POPJ	P,0		;I/O DEVICE.  LET IT THROUGH.
	PUSHJ	P,TOWAT1	;CONTROLLER.  WAIT SO DON'T CLOBBER COMMANDS
	JRST	CKATOU		;THEN TRY AGAIN FOR USER LEVEL

CKATTO:	MOVSI	S,IO		;INDICATE OUTPUT
	IORB	S,DEVIOS(F)	;SET UP STATUS WORD
	HRRZ	U,DDBLDB(F)	;GET LINE ADDR IF ANY
	JUMPN	U,CKATO1	;IF HAVE ONE, SEE IF TOP LEVEL
CKATOW:	PUSHJ	P,TOWAT1	;WAIT FOR OUTPUT DONE. (WHICH
				; IS FORCED ON ATTACH)
	JRST	CKATTO		;AND SET UP LINE, TO RETURN.
CKATO1:	HLL	U,LDBDCH(U)	;GET LINE DESCRIPTOR BITS
;	PJRST UUOLDB		;FALL INTO UUOLDB

UUOLDB::MOVEI	T1,0		;MAKE LDB AGREE WITH S
	MOVE	T2,LDBDCH(U)	;REMEMBER OLD CHARACTERISTICS
	TRNE	S,IOSTEC	;TRUTH-IN-ECHOING SET?
	TLO	T1,LDLDLR	; YES
	TRNE	S,IOSFCS	;FULL-CHARACTER-SET SET?
	TLO	T1,LDLFCS	; YES
	TRNE	S,PIMMOD	;IS THIS PACKED IMAGE MODE?
	TLOA	T1,LDLPIM	; YES, SET FLAG IN LDB (AND FORCE NO ECHO)
	TRNE	S,IOSNEC	;NO ECHO BY PROGRAM?
	TLO	T1,LDLNEC	; YES
;THIS SHOULD NO LONGER BE NEEDED, ONLY TT?CHK SHOULD SET/CLEAR IT
;	TRNE	S,IOSBKA	;SINGLE CHARACTER MODE?
;	TLO	T1,LDLBKA	; YES

	IORM	T1,LDBDCH(U)	;SET THOSE NEEDING SETTING
;	TLC	T1,LDLNEC+LDLFCS+LDLDLR+LDLBKA+LDLPIM
	TLC	T1,LDLNEC+LDLFCS+LDLDLR+LDLPIM
	ANDCAB	T1,LDBDCH(U)	;AND CLEAR THE OTHERS

IFN FTCIMP,<			;(110)
	TRNN	T2,LDRIMP	;(110) IS THIS AN IMP?
	JRST	UUOLD2		;(110) NO, DON'T MESS
	PUSH	P,T3		;(110) YES - SAVE ANOTHER AC
	MOVE	T3,T1		;(110) SEE IF LDLNEC CHANGED (1 AFTER XOR)
	XOR	T3,T2		;(110) XOR IN OLD BITS
	TLNN	T3,LDLNEC	;(110)
	JRST	UUOLD1		;(110) ZERO, DIDN'T CHANGE
	PUSH	P,T2		;(110) SAVE SOME AC'S
	PUSH	P,T1		;(110)
	MOVEI	T3,400+.TNIAC##	;(110)
	PUSHJ	P,CCTYO9	;(110) SEND TELNET CONTROL/ESCAPE
	MOVE	T3,LDBDCH(U)	;(110) GET CURRENT STATE OF NO-ECHO
	TLNN	T3,LDLNEC	;(110) IF ON, TRY TO DO IT, BUT...
	 SKIPA	T3,[400+.TNWNT##] ;(110) (ON: LET THE OTHER GUY DO IT)
	MOVEI	T3,400+.TNWIL##	;(110) (OFF:) ...DON'T SAY THAT WE WILL DO IT
	PUSHJ	P,CCTYO9	;(110) SEND WHATEVER DECIDED ON
	MOVEI	T3,400+.TOECH##	;(110) FOLLOW WITH ECHO NEGOTIATION CODE
	PUSHJ	P,CCTYO9	;(110) AND SEND THAT TOO
	POP	P,T1
	POP	P,T2		;(110) RESCUE OPERATIONS
UUOLD1:	POP	P,T3		;(110) RESCUE THE STACK
UUOLD2:	
> ;(110) END FTCIMP
	CAME	T2,T1		;DON'T SEND STATUS IF NO CHANGE
	PJRST	SETCHP		;NOTE THAT TERMINAL CHARACTERISTICS CHANGED
	POPJ	P,		;NO CHANGE
;HERE FROM UUOCON WHEN A TTY HAS BEEN INITED.

TTYOPN::HRRZ	U,DDBLDB(F)	;GET LDB ADDRESS
	JUMPE	U,TPOPJ1##	;FORGET IT IF DETACHED
	MOVSI	T2,LDLCOM	;GET COMMAND LEVEL BIT
	MOVSI	T1,TTYATC	;IS TTY CONTROLLING THE JOB?
	TDNN	T1,DEVMOD(F)	;OR IS IT AN I/O DEVICE?
	ANDCAM	T2,LDBDCH(U)	;I/O PUT IT AT USER LEVEL
	PUSHJ	P,UUOLDB	;SETUP THE LDB FROM S
	PUSHJ	P,SETCHP	;MAKE SURE THE FRONT END KNOWS ABOUT THIS
	JRST	TPOPJ1##	;AND RETURN
;TWAITI  --  WAIT FOR INPUT (CHARACTER OR LINE MODE)

TWAITI:	TRNE	S,IOSBKA	;BREAK ON ALL CHARACTERS?
	JRST	TWAITC		;YES, WAIT FOR A SINGLE CHARACTER
				;FALL INTO TWAITL (EVEN FOR IMAGE MODES)

;TWAITL  --  WAIT FOR AN INPUT LINE

TWAITL:
IFN FTTVP,<PUSHJ P,CLRPCT>	;CLEAR LINE COUNT FOR AUTO-PAGE MODE
	PUSHJ	P,CKATTI	;FIRST WAIT FOR ATTACH. SET DDB AND LINE
	PUSHJ	P,TTLCHK	;CHECK FOR A LINE BEING PRESENT
	  JRST	TWATLK		;BE SURE
	POPJ	P,		;LINE PRESENT, RETURN

TWATL1:	PUSHJ	P,TIWAIT	;NO. GO WAIT FOR ONE.
	TRNE	S,IODERR	;GOT A ↑C?
	POPJ	P,		;YES, LINE PRESENT
	PUSHJ	P,CKATTI	;MAKE SURE DIDN'T DETACH DURING WAIT
	PUSHJ	P,TTLCHK
	  JRST	TWATLK
	POPJ	P,

TWATLK:	MOVE	S,[XWD IOW,IOACT]	;FLAG ACTIVE AND WAITING SO
	IORB	S,DEVIOS(F)	;INTERRUPT WILL NOT FIND HIM ACTIVE
	PUSHJ	P,TTLCHK	;BUT NOT WAITING.  THEN LOOK AGAIN
	  JRST	TWATL1		;NOTHING ARRIVED SINCE LAST TEST
	MOVE	S,[XWD IOW,IOACT]	;SOMETHING DID SNEAK IN!
	ANDCAB	S,DEVIOS(F)	;SO FORGET ABOUT WAITING
	POPJ	P,



;SUBROUTINE TO WAIT FOR SINGLE CHARACTER INPUT

TWAITC:
IFN FTTVP,<PUSHJ P,CLRPCT>	;CLEAR LINE COUNT FOR AUTO-PAGE MODE
	PUSHJ	P,CKATTI	;MAKE SURE ATTACHED
	PUSHJ	P,TTCCHK	;CHECK FOR A CHARACTER PRESENT
	  SKIPA			;NONE PRESENT, GO WAIT
	POPJ	P,0		;YES. RETURN
	MOVE	S,[XWD	IOW,IOACT]	;SET BOTH ON TO AVOID RACE WITH COMPLETION
	IORB	S,DEVIOS(F)	;SO NOT GO INTO TI WITH SOMETHING THERE
	PUSHJ	P,TIWAIT	;NO. GO WAIT FOR ONE
	TRNE	S,IODERR	;GOT A ↑C?
	POPJ	P,		;YES, THAT'S ENOUGH
	JRST	TWAITC		;MAKE SURE ONE THERE IN CASE OF ↑C
;TTICHK  --  CHECK IF ANY INPUT IS AVAILABLE, LINE OR CHARACTER MODE
;CALL IS:
;
;	PUSHJ	P,TTICHK
;	  NO INPUT AVAILABLE
;	INPUT IS AVAILABLE
;
;THE CALLER MUST SETUP U, F, AND S APPROPRIATELY (TTLCHK AND TTCCHK
;DON'T REQUIRE F AND S, BUT TTICHK DOES).
;
;TTLCHK IS THE ROUTINE THAT HANDLES REGULAR ASCII LINE MODE, AS
;AS THE IMAGE MODES, TTCCHK HANDLES ASCII CHARACTER MODE.

TTICHK:	TRNE	S,IOSBKA	;BREAK ON ALL CHARACTERS MODE?
	JRST	TTCCHK		;YES, LOOK FOR JUST A SINGLE CHARACTER
				;NO, FALL INTO TTLCHK (EVEN FOR IMAGE MODES)

;TTLCHK  --  CHECK IF AN INPUT "LINE" IS AVAILABLE

TTLCHK::MOVSI	T1,LDLBKA	;CLEAR BREAK ON ALL CHARACTERS BIT
	ANDCAM	T1,LDBDCH(U)	;IN LINE DATA BLOCK
TTLCK2:	TRNN	F,-1		;DO WE REALLY HAVE A DDB?
	SETZ	S,		;NO DDB, NO I/O STATUS
	SKIPLE	T1,LDBTIC(U)	;ANY INPUTTABLE CHARACTERS?
	TRNN	S,I!PIMMOD	;YES, IMAGE MODE OF SOME SORT?
	SKIPLE	LDBBKC(U)	;LINE MODE, ANY LINES AVAILABLE?
	JRST	CPOPJ1##	;INPUT AVAILABLE
	CAIL	T1,↑D70		;NO LINES, GOT LOTS OF CHARACTERS?
	JRST	CPOPJ1##	;YES, CLOSE ENOUGH, WAKE UP USER
	TLNE	U,LDLIMI	;NO. IMAGE INPUT STATE?
	TLNN	S,FRCEND	;YES. ALSO TIMED OUT?
	PJRST	STRTDL		;ECHO ONE DEFERRED LINE IF NEEDED
	JRST	CPOPJ1##	;IMAGE TIME OUT, WAKE UP HIGHER-UPS

;TTCCHK  --  CHECK IF  AN ASCII CHARACTER IS AVAILABLE

TTCCHK:	MOVSI	T1,LDLBKA	;SET "BREAK ON ALL CHARACTERS" BIT
	IORM	T1,LDBDCH(U)	;IN LINE DATA BLOCK
	SKIPLE	LDBTIC(U)	;IS THERE A CHARACTER ALREADY?
	JRST	CPOPJ1##	;YES, SKIP RETURN
	PJRST	STRTDC		;NO, ECHO ONE DEFERRED CHARACTER IF NEEDED
;SUBROUTINE TIWAIT TO WAIT FOR SOME INPUT, AND SEND XON IF NEEDED.

TIWAIT:
IFN FTMIC,<			;IF MIC
	SKIPE	LDBMIC(U)	;MIC RUNNING FOR THIS LINE?
	PUSHJ	P,MICWAK	;YES, WAKE MIC IF NECESSARY
> ;END OF IF MIC
	MOVEI	T1,LDRPTY	;IS THIS LINE PTY-DRIVEN?
	TDNE	T1,LDBDCH(U)	;CHECK	IN THE LDB CHARACTERISTICS
	PUSHJ	P,PTYOW##	;YES. GO MARK THIS WAIT.
IFN FTCAFE,<IFN FT2741!FTNET,<	;IF WE SUPPORT 2741'S ON THE DC76
	PUSHJ	P,UNLKBD	;UNLOCK KEYBOARD
> ;END FT2741
> ;END FTCAFE
	MOVSI	S,IO+TTYOUW	;MARK DIRECTION AS INPUT.
	ANDCAB	S,DEVIOS(F)	;CLEAR IN CORE
	MOVEI	T1,IMGTIM	;TIMEOUT FOR IMAGE MODE
	TRNE	S,I		;TERMINAL IN IMAGE MODE?
	DPB	T1,LDPTIM	;YES. STORE TIMEOUT TIME
	PUSHJ	P,CHKXON	;SEND X-ON IF NEEDED
	JRST	WSYNC##		;WAIT FOR INPUT



;SUBROUTINE TO START DEFERRED ECHO
;CALL
;	MOVEI	T2,BIT (EITHER L1RDEL FOR LINE OR L1RDEC FOR CHARACTER)
;	PUSHJ	P,STRTDE
;	<ALWAYS RETURNS HERE>

STRTDC::MOVEI	T2,L1RDEC	;THE ALLOW-ONE-CHARACTER-TO-ECHO BIT
	TDNN	T2,LDBBYT(U)	;IS IT ALREADY SET, OR
	SKIPLE	LDBTIC(U)	;ARE ANY CHARACTERS AVAILABLE?
	POPJ	P,		;YES, DON'T ECHO ANY MORE
	JRST	STRTDE		;COMMON CODE

STRTDL::MOVEI	T2,L1RDEL	;THE ALLOW-ONE-LINE-TO-ECHO BIT
	TDNN	T2,LDBBYT(U)	;IS IT ALREADY SET, OR
	SKIPLE	LDBBKC(U)	;ARE ANY LINES AVAILABLE?
	POPJ	P,		;YES, DON'T ECHO ANY MORE

STRTDE::IORM	T2,LDBBYT(U)	;SET BIT ALLOWING LINE OR CHARACTER
	MOVEI	T2,L1RDEM	;GET DEFERRED ECHO MODE BIT
	TDNE	T2,LDBBYT(U)	;DEFERRED?
	SKIPG	LDBECC(U)	;AND INPUT WAITING?
	PJRST	CHKXON		;NOT DEFERRED, OR NO INPUT WAITING
				; MAKE SURE WE ARE ACCEPTING INPUT
	PJRST	TOPOKE		;GET OUTPUT STARTED
;ROUTINE TO CHECK IF AN XOFF HAS BEEN SENT OUT
;AND IF SO, TO SEND AN XON.
;CALLED BY:
;	PUSHJ	P,CHKXON
;	RETURN HERE ALWAYS (CLOBBERS T1,T3)


CHKXON::MOVSI	T1,LPLXOF	;IS PAGE MODE ENABLED?
	TDNN	T1,LDBPAG(U)	;GUARANTEE XON IF TALKING TO
				;ANOTHER COMPUTER
	POPJ	P,		;XON IS NOT NEEDED

CHKXN1:	MOVE	T1,LDBTIC(U)	;GET # OF INPUT CHARS
	ADD	T1,LDBECC(U)	;PLUS THOSE TO BE ECHOED
	CAILE	T1,↑D80		;TOO MANY?
	POPJ	P,		;YES, GO AWAY
	MOVSI	T1,LPLXOF	;CLEAR XOFF BIT
	ANDCAM	T1,LDBPAG(U)	;SO ONLY ONE XON IS SENT
	MOVE	T2,FLPXON	;GET POINTER TO XON
	PUSHJ	P,SETXNP	;NOTE THAT WE HAVE FILLERS
	PJRST	TOPOKE		;START TERMINAL MOVING
				;IFN FTTPAG

;ROUTINE TO GET DDB OUT OF TI WAIT IF NEEDED
;CALLED BY:
;	MOVE	J,JOB #
;	PUSHJ	P,CLRTI
;	RETURN	HERE
;RESPECTS	T1,T2
CLRTI::	PUSH	P,T1		;SAVE SOME AC'S
	PUSH	P,T2
	LDB	T1,PJBSTS##	;GET WAIT STATE CODE
	CAIE	T1,TIOWQ##	;IN TI WAIT?
	JRST	CLRTI1		;NO--EXIT
	PUSHJ	P,TTYSRC	;FIND TTY DDB
	  JRST	CLRTI1		;NO DDB?
	MOVE	T1,[IOW,,IOACT]
	ANDCAM	T1,DEVIOS(F)
CLRTI1:	POP	P,T2
	JRST	TPOPJ##

IFE FT2741,<
UNLKBD==CPOPJ##
>
IFN FT2741,<			; WITH 2741 SUPPORT
;SUBROUTINE TO UNLOCK 2741 KEYBOARD:
;CALL WITH:
;	MOVEI	U,ADDRESS-OF-LDB
;	PUSHJ	P,UNLKBD
;	RETURN HERE
UNLKBD:	MOVEI	T1,LDR2741	;SET UP 2741 BIT
	TDNE	T1,LDBDCH(U)	;...
	JRST	UNLKB1		;IF A 2741
	MOVEI	T1,L2RXON	;SET UP XON BIT
	TDNN	T1,LDBBY2(U)	;SKIP
	POPJ	P,		;IF NEITHER A 2741 OR XON SET
UNLKB1:	SKIPN	LDBBKC(U)	;DON'T GIVE UP IF HAVE BRK CHAR
	SKIPL	LDBDCH(U)	;SKIP IF NOT OUTPUT IN PROGRESS
	POPJ	P,0		;JUST RETURN
	PUSH	P,T2		;SAVE T2
	PUSH	P,T3		;AND T3
	MOVEI	T1,ISRLPC	;FUNCTION
	MOVEI	T3,<LPCUKB>B27	;SUBFUNCTION
	PUSHJ	P,@LDBISR(U)	;CALL D76INT (OR WHATEVER)
	POP	P,T3		;RESTORE T3
	PJRST	T2POPJ##	;RESTORE T2 AND RETURN
>;IFN FT2741



IFN FTMSGSER,<
;SUBROUTINE TO RETURN TTY OUTPUT FEASIBILITY FOR A MPX-CONTROLLED TTY
;CALL WITH F/ADDRESS OF TTY DDB
;RETURN WITH T1/0 IF NO OUTPUT OR 1 IF OK TO OUTPUT

TTYOFE::HRRZ	T2,DDBLDB(F)	;ADDRESS OF TTY LDB
	MOVE	T1,LDBTOC(T2)	;COUNT OF OUTPUT CHARACTERS STILL WAITING
	HLL	T1,LDBDCH	;FLAG BITS
	TDNE	T1,[LDLSTP+777740]  ;IF ↑S'ED OR MORE THAN 32 CHARACTERS
	TDZA	T1,T1		;SAY OUTPUT NOT FEASIBLE
	MOVEI	T1,1		;OTHERWISE GIVE GO AHEAD
	POPJ	P,		;RETURN TO MSGSER
> ;END IFN FTMSGSER
IFN FTCIMP,<			;(110)

;(110) ROUTINE TO ENSURE THAT A NEW QUOTE/ESCAPE CHARACTER IS REASONABLE
;(110)   AND DISTINCT FROM ALL OTHERS, ANDTOSTORE IT IF SO.
;(110) CALL:

;(110) 	MOVEI	T3, ...7-BIT ASCII CHAR...
;(110) 	MOVEI	T4, CODE: 0=QUOTE, 1=SHIFT, 2=LCLESC, 3=NETESC
;(110) 	PUSHJ	P,QUOCHK##
;(110) 	  ERROR RETURN - ILLEGAL CHAR OR NOT UNIQUE
;(110) 	NORMAL RETURN - T3 STORED APPROPRIATELY IN LDBQUO(U)

;(110) U SHOULD BE SET UP. T1, T2 USED.

QUOCHK::JUMPE	T3,QUOTOK	;(110) ALWAYS LEGAL TO CLEAR QUOTES
	PUSHJ	P,SPCHEK	;(110) CHECK FOR SPECIAL CHARACTERS
	 JFCL			;(110)
	CAIE	T3,15		;(110) DON'T ALLOW CR
	TLNE	T1,CHBRK	;(110) OR ANY BREAK CHAR
	POPJ	P,		;(110) BAD BOY!
	CAIL	T3,"A"		;(110) NOR ARE ALPHABETICS ALLOWED
	CAILE	T3,"Z"+40	;(110) ...
	JRST	QUOCK0		;(110) OK SO FAR
	CAILE	T3,"Z"			;(110)
	CAIL	T3,"A"+40		;(110)
	POPJ	P,		;(110) IF EPFTO'U LOPX IJT BMQIBCFU
QUOCK0:	MOVEI	T1,NQUPTS-1	;(110) START THE COUNTER
QUOCK1:	LDB	T2,LDPQTB(T1)	;(110) GET AN EXISTING QUOTE/ESCAPE
	CAIE	T1,(T4)		;(110) IF NOT THE SAME AS THE ONE WE ARE SETTING,
	CAIE	T3,(T2)		;(110) IS IT THE SAME AS THE GIVEN CHAR? (THIS
				;(110) ALLOWS USER TO SET QUOTE TO CURRENT VALUE -
				;(110) REDUNDANT, BUT HARMLESS - LIKE DEAD YEAST
	SOJGE	T1,QUOCK1	;(110) TRY THEM ALL
	JUMPGE	T1,CPOPJ	;(110) IF DIDN'T TRY ALL, NOT SO HARMLESS
QUOTOK:	DPB	T3,LDPQTB(T4)	;(110) OK - STORE AS NEW QUOTE/ESCAPE
	JRST	CPOPJ1##	;(110) "ESCAPE"
> ;(110) END FTCIMP
;ROUTINE TO PUT SIXBIT NAME IN DEVNAM(DDB), AND TO SET PUNIT.

;CALL:	SET DDB TO DEVICE DATA BLOCK TO RECEIVE THE NAME AND UNIT
;	SET LINE TO LINE DATA BLOCK WHERE LINE NUMBER WILL BE FOUND
;	AND SET OR CLEAR IMAGE BIT IN DEVMOD DEPENDING ON
;	WHETHER THIS LINE WILL BE PTY-DRIVEN OR NOT
;	PUSHJ P,SCNNAM
;	RETURN
;CLOBBERS T1 AND T3


SCNNAM:	PUSH	P,T2		;SAVE T2
	PUSHJ	P,TTYNAM	;BUILD NAME OF DEVICE
	MOVEM	T2,DEVNAM(F)	;STORE IN DDB
	POP	P,T2		;RESTORE T2
	LDB	T1,LDPLNO	;GET PHYSICAL LINE NUMBER
	DPB	T1,PUNIT##	;AND STORE IT IN THE DDB
	SETZM	DEVSTS(F)
	MOVEI	T3,<1←I>	;GET IMAGE MODE BIT.
	IORM	T3,DEVMOD(F)	;SET IT IN THE DDB
	MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNE	T1,LDRPTY	;IS THIS A PTY?
	ANDCAM	T3,DEVMOD(F)	;YES. CLEAR THE BIT.
	POPJ	P,0		;RETURN FROM SCNNAM


;SUBSIDIARY ROUTINE TO DO RADIX PRINT TO CORE.

SCNNMR:	IDIVI	T1,10		;DEVICE NAMES ARE OCTAL
	HRLM	T1+1,0(P)	;STORE A DIGIT ON STACK
	SKIPE	T1		;NEED MORE DIGITS?
	PUSHJ	P,SCNNMR	;YES. GO MAKE THEM.
	HLRZ	T1,0(P)		;RETRIEVE A DIGIT FROM STACK
	ADDI	T1,"0"-40	;CONVERT TO SIXBIT
	IDPB	T1,T3		;STORE IN OBJECT WORD (DEVNAM)
	POPJ	P,0		;POP UP TO SCNNMR OR BACK TO SCNNAM
IFN FTNET,<

;ROUTINE TO LOCATE A NEW TTY DDB

SETSTA:	PUSHJ	P,FNDSTA	;FIND STATION
	DPB	T1,PDVSTA##	;PUT STA # IN DEVICE LOC FIELD
	POPJ	P,		;RETURN

FNDSTA::MOVE	T1,LDBDCH(U)	;GET TTY BITS
	TRNN	T1,LDRPTY	;TERMINAL A PTY LINE?
	JRST	DDBRL		;NO - BRANCH FOR REAL TERMINAL
	LDB	T1,LDPLNO	;YES, GET LINE NUMBER ONLY
	SUBI	T1,PTYOFS##	;DECREMENT TO PTY LINE NUMBER
	PUSH	P,F		;SAVE TTY DDB FOR A SECOND
	MOVE	F,PTYTAB##(T1)	;GET PTY DDB
	LDB	T1,PDVSTA##	;GET LOCATION OF PTY
	JRST	FPOPJ##		;RESTORE TTY DDB AND RETURN TO CALLER

DDBRL:	TRNN	T1,LDRREM	;REMOTE STATION TERMINAL?
	JRST	DDBRL1		;NO, MUST BE A LOCAL TERMINAL
	LDB	T1,LDPRNN	;YES, GET THE REMOTE NODE NUMBER
	JUMPE	T1,DDBRL1	;LOCAL(?)
	POPJ	P,		;RETURN.

DDBRL1:	MOVEI	T1,LOCSTA##	;LOCAL STATION
	POPJ	P,		;RETURN


>
;ROUTINE TO ESTABLISH DEVICE OPR IF POSSIBLE
;CALL:	MOVE	T1,DEVICE NAME
;	PUSHJ	P,STDOPR
;RETURN CPOPJ IF ILLEGAL
;SKIP RETURN WITH DEVICE CHANGED
STDOPR::PUSHJ	P,TTYPHY	;LOOK FOR THIS PHYSICAL NAME
	  POPJ	P,		;FAILED IF NOT POSSIBLE
	HRRZM	U,OPRLDB##	;SAVE NEW LDB ADDRESS
	MOVEM	T1,DEVOPR##	;SAVE NEW NAME
	JRST	NETOPR##	;TELL NETWORK THAT OPR CHANGED
	SUBTTL	ROUTINES FOR PTY

;PTYPUT IS CALLED FROM PTYSER TO PLACE A CHARACTER IN A TERMINAL INPUT
;BUFFER AS THOUGH THE TERMINAL HAD BEEN TYPED ON. NO ECHOING IS ALLOWED,
;THOUGH AND THIS ROUTINE IS A SIMPLIFIED VERSION OF RECINT AND
;XMTECH, TO MAKE THE CHARACTERS VISIBLE TO THE CONTROLLED JOB WITHOUT ECHOING
;CALL
;	MOVE	T3,CHAR
;	MOVE	T1,CHAR BITS FROM SPCHEK
;	PUSHJ	P,PTYPUT
;	  ERROR	RETURN
;	  NORMAL RETURN

CNTRLO==17
PTYPUT::PUSHJ	P,SAVE1##	;PRESERVE P1
	MOVSI	P1,LDLFSP	;THE FULL-SCNSER-SERVICE BIT
	TDNE	P1,LDBTTW(U)	;IS THIS PTY BEING A TTY?
	JRST	PTYPT1		;YES, LET SCNSER DO CHARACTER HANDLING
	TLNE	T1,CHALT	;POSSIBLE ALTMODE?
	PUSHJ	P,RIALTO	;YES, CONVERT IF WANTED
	MOVE	P1,T1		;SAVE BITS IN P1
ifn ftcimp,<	;(270) incase some clown is cross patched out over a PTY.
	SKIPN	f,LDBIMP(U)	;(270) CROSSPATCHED TO IMP?
	  JRST	PtyNCP		;(270) NO.
	pushj	p,RecQuo	;(270) is it something the NET wants to know?
	  pjrst	cpopj1##	;(270) yes, thank you.  we handled it.
	  popj	p,		;(270) yes, but we ran into a problem.
	;(270) not ours.  continue looking
PtyNCP:	; not cross patched
> ;(270) end of ifn FTCIMP
	CAIN	T3,CNTRLO
	PJRST	FLPCNO
IFN FTMIC,<			;IF MIC
	SKIPE	LDBMIC(U)
	CAIE	T3,1		;CONTROL A COUNTS AS ↑C TO MIC
> ;END OF IF MIC
	CAIN	T3,3		;CONTROL C?
	JRST	PTYCC		;YES. SPECIAL CHECKING
IFN FTWATCH,<
	CAIN	T3,"T"-100
	JRST	PTYCT
PTYINA:>
	MOVSI	T2,L2LCCS	;NOT CONTROL C, SO
	ANDCAM	T2,LDBBY2(U)	;CLEAR SYNC BIT
IFN FTMIC,<			;IF MIC
	SKIPE	T2,LDBMIC(U)
	JRST	PTYMCK
> ;END OF IF MIC


;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

PTYPT1:	MOVE	T2,LDBTIC(U)	;IS THIS LINE ALREADY FULL?
	CAIG	T2,↑D200	; ..
	SKIPG	TTFREN##	;OR LISTS EXHAUSTED?
	POPJ	P,0		;YES. DISCARD CHAR
	SKIPN	TTFTAK		;ANY FREELIST
	POPJ	P,0		;NO--PUNT
	AOS	(P)		;GOING TO GIVE GOOD RETURN NOW
	MOVSI	T2,LDLFSP	;THE FULL-SCNSER-PTY BIT
	TDNE	T2,LDBTTW(U)	;IS THIS UNDER FULL SCNSER CONTROL?
	PJRST	RECPTY		;YES, ENTER AT THE TOP
IFN FTMIC,<			;IF MIC
	MOVE	T1,P1		;SETUP CHARACTER BITS FOR MICECH
	SKIPE	LDBMIC(U)
	PUSHJ	P,MICECH	;SAY COL1 TO MIC
> ;END OF IF MIC
	SCNOFF			;NO INTERRUPTION
	STCHK	T3,LDBTIP(U)	;STORE CHARACTER
	TLNE	P1,CHBRK	;IS THIS A BREAK CHARACTER?
	PUSHJ	P,SETBKU	;YES, STORE LAST BREAK POINTER
	LDCHK	T3,LDBECT(U)	;TAKE CHARACTER NEEDING ECHO
	TLNE	P1,CHBRK	;BREAK CHAR?
	AOS	LDBBKC(U)	;YES. COUNT BREAKS
	AOS	T2,LDBTIC(U)	;ADVANCE TYPEIN COUNT
	SCNON			;ALLOW INTERRUPTS AGAIN
	TLNE	U,LDLBKA	;TERMINAL IN BREAK-ON-ALL MODE?
	PUSHJ	P,RCVWKQ	;YES. WAKE JOB IF WAITING
	CAIG	T2,↑D79		;ENOUGH TO WAKE ON?
	TLNE	P1,CHBRK	;OR A BREAK CHARACTER?
	PUSHJ	P,ECHBRK	;YES. WAKE THE JOB
	POPJ	P,		;SUCCESSFUL RETURN TO PTYSER
;MORE OF PTYPUT. SPECIAL CODE FOR CONTROL C

PTYCC:
IFN FTMIC,<			;IF MIC
	SKIPE	T1,LDBMIC(U)
	PUSHJ	P,MICRIC
> ;END OF IF MIC
	PUSHJ	P,RIDLN		;YES. DO SO.
	MOVSI	T1,L2LCCS	;SECOND CONTROL C?
	TDNE	T1,LDBBY2(U)	; ..
	PUSHJ	P,CNCCHK	;YES. FORCE CONTROL C IF POSSIBLE
	  JRST	PTYCC1		;NOT SECOND--GO SET BIT
	  JRST	PTYCC4		;NO. (JACCT) JUST PASS THE CHARACTER
	PUSHJ	P,TSETBI	;YES. CLEAR BUFFERS
	PUSHJ	P,TSETBO	; ..
	JRST	CPOPJ1##

PTYCC4:	PUSHJ	P,TTHALT	;FORCE .HALT COMMAND
PTYCC1:	MOVSI	T1,L2LCCS	;SET "↑C LAST IN" BIT
	IORM	T1,LDBBY2(U)	;SET BIT FOR NEXT TIME
	JRST	PTYPT1		;AND GO STORE CONTROL C IN INPUT BUFFER


;HERE ON ↑O TO PTY

FLPCNO:	MOVEI	T1,LDROSU	;FLIP THE ↑O BIT WHEN PTY OR REMOTE
	XORM	T1,LDBDCH(U)	;SENDS ↑O
	PUSHJ	P,TSETBO	;CLEAR THE OUTPUT BUFFER
	PJRST	XMTWAK		;WAKE JOB IF IN OUTPUT WAIT
IFN FTWATCH,<
PTYCT:	PUSHJ	P,DOCTLT
	  JRST	PTYINA
	  JRST	TTFRC1
	JRST	CPOPJ1##
>
;SUBROUTINE TO SET DEFAULT TERMINAL CHARACTERSTICS
;CALLING SEQUENCE:
;	MOVEI	T1,TERMINAL TYPE
;	MOVE	U,ADDRESS OF THE LDB
;	PUSHJ	P,SETTTC
;	ALWAYS RETURN HERE

SETTTC::MOVE	T2,T1
	JUMPGE	T1,SETTT1	;CUSTOMER DEFINED TYPE ?
	MOVNS	T2		;YES
	TRO	T2,100		;CUSTOMER TYPES ARE 101-177
SETTT1:	DPB	T2,LDPTTT	;STORE TERMINAL TYPE
	LSH	T1,1		;2 WORDS PER ENTRY
	LDB	T2,TTPWID	;WIDTH
	DPB	T2,LDPWID	;STORE THAT
	LDB	T2,TTPPSZ	;PAGE SIZE
	DPB	T2,LDPPSZ	;STORE THAT
	LDB	T2,TTPFLC	;FILLER CLASS
	DPB	T2,LDPFLC	;STORE THAT
	LDB	T2,TTPFRM	;FORM FEED
	DPB	T2,LDPFRM	;STORE THAT
	LDB	T2,TTPTAB	;TABS
	DPB	T2,LDPTAB	;STORE THAT
	LDB	T2,TTPLCT	;LOWER CASE
	DPB	T2,LDPLCT	;STORE THAT
	LDB	T2,TTPALT	;ALTMODE CONVERSION
	DPB	T2,LDPALT	;STORE THAT
	LDB	T2,TTPDIS	;GET DISPLAY SETTING
	DPB	T2,LDPDIS	;STORE THAT
	POPJ	P,		;RETURN
IFN FTCIMP,<			;(110)
	SUBTTL	ROUTINES FOR IMP SUPPORT


;(110) ROUTINE TO SET UP A TTY-TO-IMP CROSSPATCH (THEREAFTER ADDRESSED AS
;(110)  HIS NASTINESS)

;(110) 	MOVE	F,[IMP DDB ADDRESS]
;(110) 	MOVE	J, JOB NUMBER
;(110) 	PUSHJ	P,TTYIMP##
;(110) 	ALWAYS RETURN HERE (NO CONNECTION MADE IF ERROR)
;(110) 	  RETURNS LDB POINTER IN T1

TTYIMP::PUSH	P,U		;(110) SAVE OLD U (NEEDED BY NCP)
	SKIPE	U,TTYTAB(J)	;(110) GET TTY DDB ADDRESS
	HRRZ	U,DDBLDB(U)	;(110) FOLLOW POINTER TO LDB
	JUMPE	U,TTYIM2	;(110) FORGET IF NONEXISTENT OR DETACHED
	LDB	T1,LDPLCL	;(110) GET LOCAL ESCAPE CHARACTER
	JUMPN	T1,TTYIM1	;(110) IS THERE ONE DEFINED?
	MOVEI	T1,037		;(110) NO - PREVENT USER FROM NOT BEING ABLE TO
	DPB	T1,LDPLCL	;(110) TO ESCAPE BY GIVING HIM DEFAULT (↑←)
TTYIM1:	HRRZM	F,LDBIMP(U)	;(110) STORE IMP POINTER IN LDB
TTYIM2:	MOVEI	T1,(U)		;(110) COPY LDB ADDRESS INTO T1
	JRST	UPOPJ##		;(110) RESTORE U AND RETURN


;(110) SUBROUTINE TO HANDLE TTY INPUT TO CROSSPATCHED TTY

TTIMPI:
;(XXX)	CAIN	T3,15		;(110) CR AND NOT IMAGE MODE?
;(XXX)	TLNE	U,LDLXON	;(110) YES - DON'T WAKE IMP IF NOT PAPER TAPE MODE
	PUSHJ	P,RQTIIO##	;(110) REQUEST IMP PROCESSING OF TTY DATA
	SETZ	T1,		;(110) SIGNAL NOT A NORMAL BREAK CHAR
	POPJ	P,		;(110) RETURN

;(110) SUBROUTINE CALLED FROM IMP SERVICE TO GET A CHARACTER
;(110)   FROM THE INPUT BUFFER OF A CROSSPATCHED TTY.
;(110)   ENTER WITH LDB ADDRESS IN U.
;(110)   SKIP RETURNS 9-BIT CHAR IN T3.
;(110)   NON-SKIP RETURN IF NONE

TTYTTI::PUSH	P,S		;(146) IN CASE CLOCK1 REALLY CARES ABOUT S
	SETZ	S,		;(146) MAKE SURE TYI IS NOT FOOLED
	PUSHJ	P,TYI		;(146) GO GET THE CHARACTER
	 SKIPA			;(146) NONE LEFT
	AOS	-1(P)		;(146) GOT A CHARACTER
	POP	P,S		;(146) RESTORE S
	POPJ	P,		;(146) AND RETURN
;(110) SUBROUTINE TO SEND A CHARACTER TO A TELETYPE BUFFER.

;(110) CALLED FROM IMP INTERRUPT LEVEL.
;(110)   ENTER WITH LDB ADDRESS IN U, CHAR IN T3.
;(110)   RETURN SKIP IF OK, NON-SKIP IF NO ROOM.

TTYXMT::HLL	U,LDBDCH(U)	;(110) GET CHARACTERISTICS
	MOVEI	T1,LDROSU	;(110) GET OSU BIT FIRST
	TDNE	T1,LDBDCH(U)	;(110) IS IT ON
	PJRST	CPOPJ1##	;(110) YES - QUIT VERY QUICKLY
	MOVE	T1,TTFREN##	;(110) GET NO. OF CHUNKS AVAILABLE
	MOVE	T2,LDBTOC(U)	;(110) AND CHECK HOW MUCH NOW IN BUFFER
	CAIL	T1,3		;(110) ALWAYS LEAVE A LITTLE
	CAML	T2,TIWRNN	;(110) AND DON'T GIVE TOO MUCH TO ONE TTY
	 POPJ	P,		;(110) TOO LITTLE OR TOO MUCH - TELL IMPSER TO STOP
	AOS	(P)		;(110) CONFIDENCE
	TRNN	T3,400		;(110) IMAGE CHARACTER?
	 PUSHJ	P,PEVEN8	;(110) NO - FIX PARITY
	PJRST	TYO9A		;(110) SEND, THEN GO BACK FOR MORE

;(110) STILL IN FTCIMP
;(271);(110) SUBROUTINE TO SEND CHARACTERS TO A JOB
;(271)
;(271);(110) CALLED WITH LDB ADDRESS IN U, CHAR IN T3.
;(271);(110) SKIP RETURN IF OK, NON-SKIP IF NO ROOM.
;(271)
;(271)RECIMP::PUSHJ	P,RECPTY	;(110) CALL THE INTERRUPT STUFF. SKIP RETURN IF
;(271)	 JRST	CPOPJ1##	;(110)
;(271)	POPJ	P,		;(110) CAN'T TAKE ANY MORE (INVERSE OF USUAL)

;(110) SUBROUTINE TO ACKNOWLEDGE RECEIPT OF A CHARACTER.IN GENERAL,
;(110)  CALLS IMPTYP. CALL WITH LDB ADDRESS IN U.

XP	XMTIMP,XMTIN1

;(110) HERE FROM ICP IN NCP WHEN JUST COMPLETED A TELNET CONNECTION

XP	TTYON,DSCSET

;(110) HERE WHEN TELNET CONNECTION BROKEN

XP	TTYOFF,DSCCLR

;(110) ROUTINES TO SET/CLEAR THE NOECHO BIT IN DEVIOS, DOING THE APPROPRIATE
;(110)  LINE HANDLING. SENDING TELNET CONTROL CODES, ETC.

;(110) 	MOVE	U, LINE ADDR
;(110) 	PUSHJ	P,SETECH (TO CLEAR NOECHO)
;(110) 		  SETNEC (TO SET NOECHO)
;(110)  ALWAYS RETURN HERE;(110)  F, S CLOBBERED

SETECH::TDZA	S,S		;(110) HERE TO CLEAR THE BIT
SETNEC::MOVEI	S,IOSNEC	;(110) HERE TO SET THE BIT
	HRRZ	F,LDBDDB(U)	;(110) LOOK FOR THE ATTACHED TTY DDB
	JUMPE	F,UUOLDB	;(110) NOT AROUND (SHOULD NEVER HAPPEN)
	IORM	S,DEVIOS(F)	;(110) SET BIT IF SETTING
	XORI	S,IOSNEC	;(110) CLEAR BIT IF CLEARING (GETTIN' DIZZY)
	ANDCAB	S,DEVIOS(F)	;(110)
	PJRST	UUOLDB		;(110) MAKE LDB BITS AGREE WITH S BITS
> ;(110) END FTCIMP
;TWO SUBROUTINES TO INITIALIZE THE LDB. LDBCLR SETS UP THE BITS FROM
;INITIAL STATE FOUND IN LINTAB, THEN FALLS INTO LDBINI. LDBINI JUST
;CLEARS AS REQUIRED ON 140 RESTART.
;BOTH SHOULD BE CALLED WITH LINE SET UP.

LDBCLR::LDB	T1,LDPLNO	;GET LINE NUMBER
	LDB	T1,LNPVRG	;GET VIRGIN-STATE BITS FROM LINTAB
	TRZ	T1,4		;CLEAR INITIA BIT
	DPB	T1,LDPVR2	;STORE THEM AROUND THE LDB
	LSH	T1,-5		; ..
	DPB	T1,LDPVR1	; ..
	LSH	T1,-6		; ..
	DPB	T1,LDPFLC	;LAST IS THE FILLER CLASS
	MOVSI	T1,LDLFSP	;INITIALLY UNKNOWN TERMINAL TYPE
	ANDM	T1,LDBTTW(U)
IFN FT2741,<
	LDB	T1,LDPSPD
	MOVEI	T2,LDR2741
	CAIN	T1,104
	IORM	T2,LDBDCH(U)
>;IFN FT2741
LDBINI::MOVSI	T1,LDBCMR+LDBCMK;CLEAR COMMAND REQUEST BITS
	ANDCAM	T1,LDBDDB(U)	;IN LINE DATA BLOCK
	MOVE	T1,[LDIBCM]
	ANDCAM	T1,LDBBYT(U)	;CLEAR MOST BYTES
	MOVE	T1,LDIDCM	;CLEAR DEVICE CHARACTERISTICS
	ANDCAM	T1,LDBDCH(U)	; AS APPROPRIATE
	MOVSI	T1,LDLIDL	;GET THE IDLE BIT
	IORM	T1,LDBDCH(U)	;WHICH SHOULD NORMALLY BE SET
IFN FTCIMP,<			;(110)
	SETZM	LDBIMP(U)	;(110) CLEAR IMP RELATED WORDS
	SETZM	LDBQUO(U)	;(110)
>;(110)
	MOVEI	T1,↑D72		;INITIAL VALUE OF TERMINAL WIDTH
	DPB	T1,LDPWID	;STORE IN LDB
	MOVSI	T1,L2LCLR	;CLEAR NECESSARY BITS IN LDBBY2
	ANDCAM	T1,LDBBY2(U)	; ..
	LDB	T3,LDPLNO	;COPY LINE NUMBER
	MOVSI	T1,LDLCOM+LDLLCT;ASSUME AT COMMAND LEVEL AND UPPER CASE
IFN FTD10H,<			;CODE FOR 2741 ON DC10H
	HLRZ	T2,LINTAB##(T3)	;GET BITS FROM LINTAB
	TRNN	T2,TTVDIS##	;IS IT A DISPLAY LINE
				; WHICH INDICATES ITS A DC10H LINE?
	  JRST	.+4		;NO
	MOVSI	T2,LILCFE	;SET CLEVER BIT
	IORM	T2,LDBISR(U)	; IN THE LDB.
	TRO	T1,LDR2741	;ALSO TELL LDB ITS A 2741
>;END IFN FTD10H
IFN FTKS10,<
	MOVSI	T2,LILCFE	;CLEVER BIT
	CAIGE	T3,M.DZNL##	;IS THIS A DZ11 LINE ?
	IORM	T2,LDBISR(U)	;IS DZ11 LINE
>;IFN FTKS10

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FTCIMP,<			;(110)
	CAIL	T3,ITYFST##	;(110) IS THIS AN ITY?
	CAIL	T3,ITYFST##+ITYN## ;(110)
	JRST	LDBIMI		;(110) NO
	TLZ	T1,LDLLCT	;(110)YES, ALWAYS LOWER CASE AND AN IMP
	TRO	T1,LDRIMP
LDBIMI:>			;(110)
	CAMN	T3,BOOTCT##	;THIS THE CTY
	TRO	T1,LDRCTY	;YES--SET CTY BIT
	CAIN	T3,FRCLIN##	;THIS THE LINE RESERVED FOR THE MONITOR?
	TLZ	T1,LDLLCT	;YES, IT IS ALWAYS LC
	CAILE	T3,TCONLN##	;ABOVE TCONLN?
;(265)	TRO	T1,LDRPTY	;YES. SET PTY BIT
	tdo	T1,[xwd <ldltab!ldlfrm!ldlnfc>,LDRPTY]	;(265) set bits
	CAILE	T3,TCONLN##	;(251) did you say this was a pty?
	tlz	t1,ldllct	;(251) yes.  don't convert to upper case
	IORM	T1,LDBDCH(U)	;PUT THESE BITS IN THE LDB
	PUSHJ	P,TYOVRG	;SETUP BYTE STREAM FOR OUTPUT
	PUSHJ	P,RECVRG	;AND FOR INPUT
	PUSHJ	P,TSETBI	;YES--CLEAR INPUT BUFFER
	HRLOI	T1,LPLCLR	;CLEAR PAGE BITS
	ANDCAM	T1,LDBPAG(U)	;...
	MOVSI	T1,LPLPAG	;INITIALIZE TERMINAL TO HANDLE XON/XOFF
	IORM	T1,LDBPAG(U)	;...
	MOVSI	T1,LPLALT	;THE ALTMODE-CONVERION BIT
	XCT	TTDALT##	;IORM OR ANDCAM DEPENDING ON DEFAULT
				; FOR TERMINAL ALT (SEE COMDEV)
IFN FTMIC,<SETZM LDBMIC(U)>	;CLEAR MIC WORD
	MOVSI	T3,L1LOFL	;OFF LINE BIT
	MOVEI	T1,ISROFL
	PUSHJ	P,@LDBISR(U)
	IORM	T3,LDBOFL(U)
	POPJ	P,0		;RETURN FROM LDBINI
	SUBTTL	IMPURE DATA

	$LOW
ECHCNT:	0			;CLOCK REQUEST QUEUE COUNTER
TTBASE::0			;FIRST WORD IN TERMINAL BUFFER SPACE
IFN FTDIAL,<
DSCNUM:	BLOCK	2		;PHONE NUMBER BEING DIALLED, OR LAST DIALLED
>

.GTSCN::
;SCNSER RESPONSE DATA (%SC??? VALID ONLY IF FTRSP!FTACCT)
%SCNRI::0			;(0)  NUMBER OF CHARS (EXCLUDES MIC) RECEIVED
%SCNXI::0			;(1)  NUMBER OF CHARS (INCLUDES FILL) XMITTED
%SCNEI::0			;(2)  NUMBER OF CHARS ECHOED (SUBSET OF %SCNXI)
TIWRNN::EXP	↑D80		;(3)  MAX BUFFER SIZE
%SCNAL::0			;(4)  NUMBER OF ACTIVE LINES
RPIMWN::EXP	↑D600		;(5)  PIM BUFFER SIZE
	EXP	RECINT		;(6)  FOR MONITOR TEST
	EXP	XMTINT		;(7)  PROGRAMS
	EXP	0		;(10) WAS TYPEX
TTFTAK::0			;(11) FIRST FREE CHUNK
TTFPUT::0			;(12) LAST FREE CHUNK
SCNMXL==:<<.-.GTSCN-1>B26>
TIWRN1:	↑D80			;WORD TO SAVE OLD BUFFER LIMIT
IFN FTMODM,<			;(107)

IFN FT.DTF,<			;(107)
DSCCLK:	BLOCK	1		;(107) COUNTER FOR TIMEOUT CHECKS
>;(107)
>;(107)
	XLIST			;LITERALS UNDER XLIST
	$LIT
	LIST

SCNEND:	END